diff --git a/teavm-platform/pom.xml b/teavm-platform/pom.xml index f35121baa..a4fd22179 100644 --- a/teavm-platform/pom.xml +++ b/teavm-platform/pom.xml @@ -15,5 +15,10 @@ teavm-core ${project.version} + + junit + junit + test + \ No newline at end of file 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 f47ac1747..7b50dfe88 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 @@ -23,7 +23,7 @@ import java.lang.annotation.Target; /** *

Marks a valid resource interface. Resource interface is an interface, that has get* and set* methods, * according the default convention for JavaBeans. Each property must have both getter and setter. - * Also each property's must be either primitive value, except for long or valid resource.

+ * Also each property's must be either primitive value (except for long) or a valid resource.

* * @see MetadataGenerator * @see ResourceArray diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java index 599467059..e798f94cc 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java @@ -20,6 +20,8 @@ package org.teavm.platform.metadata; * @author Alexey Andreev */ public interface ResourceMap { + boolean has(String key); + T get(String key); void put(String key, T value); diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceArray.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceArray.java new file mode 100644 index 000000000..c8aca068d --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceArray.java @@ -0,0 +1,43 @@ +/* + * 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.util.ArrayList; +import java.util.List; +import org.teavm.platform.metadata.ResourceArray; + +/** + * + * @author Alexey Andreev + */ +class BuildTimeResourceArray implements ResourceArray { + private List data = new ArrayList<>(); + + @Override + public int size() { + return data.size(); + } + + @Override + public T get(int i) { + return data.get(i); + } + + @Override + public void add(T elem) { + data.add(elem); + } +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceGetter.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceGetter.java new file mode 100644 index 000000000..f00aa2e27 --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceGetter.java @@ -0,0 +1,33 @@ +/* + * 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 + */ +class BuildTimeResourceGetter implements BuildTimeResourceMethod { + private int index; + + public BuildTimeResourceGetter(int index) { + this.index = index; + } + + @Override + public Object invoke(BuildTimeResourceProxy proxy, Object[] args) throws Throwable { + return proxy.data[index]; + } +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceMap.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceMap.java new file mode 100644 index 000000000..36174df46 --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceMap.java @@ -0,0 +1,43 @@ +/* + * 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.util.HashMap; +import java.util.Map; +import org.teavm.platform.metadata.ResourceMap; + +/** + * + * @author Alexey Andreev + */ +class BuildTimeResourceMap implements ResourceMap { + private Map data = new HashMap<>(); + + @Override + public boolean has(String key) { + return data.containsKey(key); + } + + @Override + public T get(String key) { + return data.get(key); + } + + @Override + public void put(String key, T value) { + data.put(key, value); + } +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceMethod.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceMethod.java new file mode 100644 index 000000000..31f3be541 --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceMethod.java @@ -0,0 +1,24 @@ +/* + * 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 + */ +interface BuildTimeResourceMethod { + Object invoke(BuildTimeResourceProxy proxy, Object[] args) throws Throwable; +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxy.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxy.java new file mode 100644 index 000000000..390acb1e5 --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxy.java @@ -0,0 +1,40 @@ +/* + * 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.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Map; + +/** + * + * @author Alexey Andreev + */ +class BuildTimeResourceProxy implements InvocationHandler { + private Map methods; + Object[] data; + + public BuildTimeResourceProxy(Map methods, Object[] initialData) { + this.methods = methods; + data = Arrays.copyOf(initialData, initialData.length); + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return methods.get(method).invoke(this, args); + } +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxyBuilder.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxyBuilder.java new file mode 100644 index 000000000..b5a09e757 --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxyBuilder.java @@ -0,0 +1,203 @@ +/* + * 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.lang.reflect.Method; +import java.util.*; +import org.teavm.platform.metadata.Resource; +import org.teavm.platform.metadata.ResourceArray; +import org.teavm.platform.metadata.ResourceMap; + +/** + * + * @author Alexey Andreev + */ +class BuildTimeResourceProxyBuilder { + private Map, BuildTimeResourceProxyFactory> factories = new HashMap<>(); + private static Set> allowedPropertyTypes = new HashSet<>(Arrays.>asList( + boolean.class, Boolean.class, byte.class, Byte.class, short.class, Short.class, + int.class, Integer.class, float.class, Float.class, double.class, Double.class, + String.class, ResourceArray.class, ResourceMap.class)); + + public BuildTimeResourceProxy buildProxy(Class iface) { + BuildTimeResourceProxyFactory factory = factories.get(iface); + if (factory == null) { + factory = createFactory(iface); + factories.put(iface, factory); + } + return factory.create(); + } + + private BuildTimeResourceProxyFactory createFactory(Class iface) { + return new ProxyFactoryCreation(iface).create(); + } + + private static class ProxyFactoryCreation { + private Class rootIface; + Map> getters = new HashMap<>(); + Map> setters = new HashMap<>(); + Map methods = new HashMap<>(); + private List initialData = new ArrayList<>(); + private Map propertyIndexes = new HashMap<>(); + + public ProxyFactoryCreation(Class iface) { + this.rootIface = iface; + } + + BuildTimeResourceProxyFactory create() { + if (!rootIface.isInterface()) { + throw new IllegalArgumentException("Error creating a new resource of type " + rootIface.getName() + + " that is not an interface"); + } + scanIface(rootIface); + return new BuildTimeResourceProxyFactory(methods, initialData.toArray(new Object[initialData.size()])); + } + + private void scanIface(Class iface) { + if (iface.isAnnotationPresent(Resource.class)) { + throw new IllegalArgumentException("Error creating a new resource of type " + iface.getName() + + ". This type is not marked with the " + Resource.class.getName() + " annotation"); + } + + // Scan methods + getters.clear(); + setters.clear(); + for (Method method : iface.getDeclaredMethods()) { + if (method.getName().startsWith("get")) { + scanGetter(method); + } else if (method.getName().startsWith("is")) { + scanBooleanGetter(method); + } else if (method.getName().startsWith("set")) { + scanSetter(method); + } else { + throwInvalidMethod(method); + } + } + + // Verify consistency of getters and setters + for (Map.Entry> property : getters.entrySet()) { + String propertyName = property.getKey(); + Class getterType = property.getValue(); + Class setterType = setters.get(propertyName); + if (setterType == null) { + throw new IllegalArgumentException("Property " + iface.getName() + "." + propertyName + + " has a getter, but does not have a setter"); + } + if (!setterType.equals(getterType)) { + throw new IllegalArgumentException("Property " + iface.getName() + "." + propertyName + + " has a getter and a setter of different types"); + } + } + for (String propertyName : setters.keySet()) { + if (!getters.containsKey(propertyName)) { + throw new IllegalArgumentException("Property " + iface.getName() + "." + propertyName + + " has a setter, but does not have a getter"); + } + } + + // Verify types of properties and fill default values + for (Map.Entry> property : getters.entrySet()) { + String propertyName = property.getKey(); + Class propertyType = property.getValue(); + if (allowedPropertyTypes.contains(propertyType)) { + continue; + } + if (!propertyType.isInterface() || !propertyType.isAnnotationPresent(Resource.class)) { + throw new IllegalArgumentException("Property " + iface.getName() + "." + propertyName + + " has an illegal type " + propertyType.getName()); + } + } + // TODO: fill default values + + // Scan superinterfaces + for (Class superIface : iface.getInterfaces()) { + scanIface(superIface); + } + } + + private void throwInvalidMethod(Method method) { + throw new IllegalArgumentException("Method " + method.getDeclaringClass().getName() + "." + + method.getName() + " is not likely to be either getter or setter"); + } + + private void scanGetter(Method method) { + String propertyName = extractPropertyName(method.getName().substring(3)); + if (propertyName == null || method.getReturnType().equals(void.class) || + method.getParameterTypes().length > 0) { + throwInvalidMethod(method); + } + if (getters.put(propertyName, method.getReturnType()) != null) { + throw new IllegalArgumentException("Method " + method.getDeclaringClass().getName() + "." + + method.getName() + " is a duplicate getter for property " + propertyName); + } + methods.put(method, new BuildTimeResourceGetter(getPropertyIndex(propertyName))); + } + + private void scanBooleanGetter(Method method) { + String propertyName = extractPropertyName(method.getName().substring(2)); + if (propertyName == null || !method.getReturnType().equals(boolean.class) || + method.getParameterTypes().length > 0) { + throwInvalidMethod(method); + } + if (getters.put(propertyName, method.getReturnType()) != null) { + throw new IllegalArgumentException("Method " + method.getDeclaringClass().getName() + "." + + method.getName() + " is a duplicate getter for property " + propertyName); + } + methods.put(method, new BuildTimeResourceGetter(getPropertyIndex(propertyName))); + } + + private void scanSetter(Method method) { + String propertyName = extractPropertyName(method.getName().substring(2)); + if (propertyName == null || !method.getReturnType().equals(void.class) || + method.getParameterTypes().length != 1) { + throwInvalidMethod(method); + } + if (setters.put(propertyName, method.getParameterTypes()[0]) != null) { + throw new IllegalArgumentException("Method " + method.getDeclaringClass().getName() + "." + + method.getName() + " is a duplicate setter for property " + propertyName); + } + methods.put(method, new BuildTimeResourceSetter(getPropertyIndex(propertyName))); + } + + private String extractPropertyName(String propertyName) { + if (propertyName.isEmpty()) { + return null; + } + char c = propertyName.charAt(0); + if (c != Character.toUpperCase(c)) { + return null; + } + if (propertyName.length() == 1) { + return propertyName.toLowerCase(); + } + c = propertyName.charAt(1); + if (c == Character.toUpperCase(c)) { + return propertyName; + } else { + return Character.toLowerCase(propertyName.charAt(0)) + propertyName.substring(1); + } + } + + private int getPropertyIndex(String propertyName) { + Integer index = propertyIndexes.get(propertyName); + if (index == null) { + index = propertyIndexes.size(); + propertyIndexes.put(propertyName, index); + } + return index; + } + } +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxyFactory.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxyFactory.java new file mode 100644 index 000000000..4283bda22 --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxyFactory.java @@ -0,0 +1,38 @@ +/* + * 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.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author Alexey Andreev + */ +class BuildTimeResourceProxyFactory { + private Map methods = new HashMap<>(); + private Object[] initialData; + + public BuildTimeResourceProxyFactory(Map methods, Object[] initialData) { + this.methods = methods; + this.initialData = initialData; + } + + BuildTimeResourceProxy create() { + return new BuildTimeResourceProxy(methods, initialData); + } +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceProxy.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceSetter.java similarity index 68% rename from teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceProxy.java rename to teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceSetter.java index 5260ba845..e8caaa40d 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceProxy.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceSetter.java @@ -15,16 +15,20 @@ */ package org.teavm.platform.plugin; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; - /** * - * @author Alexey Andreev + * @author Alexey Andreev */ -class ResourceProxy implements InvocationHandler { +class BuildTimeResourceSetter implements BuildTimeResourceMethod { + private int index; + + public BuildTimeResourceSetter(int index) { + this.index = index; + } + @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + public Object invoke(BuildTimeResourceProxy proxy, Object[] args) throws Throwable { + proxy.data[index] = args[0]; return null; } } diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/DefaultMetadataGeneratorContext.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/DefaultMetadataGeneratorContext.java new file mode 100644 index 000000000..608f7fbfe --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/DefaultMetadataGeneratorContext.java @@ -0,0 +1,72 @@ +/* + * 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.lang.reflect.Proxy; +import java.util.Properties; +import org.teavm.model.ListableClassReaderSource; +import org.teavm.platform.metadata.MetadataGeneratorContext; +import org.teavm.platform.metadata.ResourceArray; +import org.teavm.platform.metadata.ResourceMap; + +/** + * + * @author Alexey Andreev + */ +class DefaultMetadataGeneratorContext implements MetadataGeneratorContext { + private ListableClassReaderSource classSource; + private ClassLoader classLoader; + private Properties properties; + private BuildTimeResourceProxyBuilder proxyBuilder = new BuildTimeResourceProxyBuilder(); + + private DefaultMetadataGeneratorContext(ListableClassReaderSource classSource, ClassLoader classLoader, + Properties properties) { + this.classSource = classSource; + this.classLoader = classLoader; + this.properties = properties; + } + + @Override + public ListableClassReaderSource getClassSource() { + return classSource; + } + + @Override + public ClassLoader getClassLoader() { + return classLoader; + } + + @Override + public Properties getProperties() { + return new Properties(properties); + } + + @Override + public T createResource(Class resourceType) { + return resourceType.cast(Proxy.newProxyInstance(classLoader, new Class[] { resourceType }, + proxyBuilder.buildProxy(resourceType))); + } + + @Override + public ResourceArray createResourceArray() { + return new BuildTimeResourceArray<>(); + } + + @Override + public ResourceMap createResourceMap() { + return new BuildTimeResourceMap<>(); + } +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/MetadataProviderNativeGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/MetadataProviderNativeGenerator.java new file mode 100644 index 000000000..9d9c2a8dd --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/MetadataProviderNativeGenerator.java @@ -0,0 +1,43 @@ +/* + * 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.codegen.SourceWriter; +import org.teavm.javascript.ni.Generator; +import org.teavm.javascript.ni.GeneratorContext; +import org.teavm.model.*; +import org.teavm.platform.metadata.MetadataProvider; + +/** + * + * @author Alexey Andreev + */ +class MetadataProviderNativeGenerator implements Generator { + @Override + public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { + ClassReader cls = context.getClassSource().get(methodRef.getClassName()); + MethodReader method = cls.getMethod(methodRef.getDescriptor()); + AnnotationReader providerAnnot = method.getAnnotations().get(MetadataProvider.class.getName()); + if (providerAnnot == null) { + return; + } + if (!method.hasModifier(ElementModifier.NATIVE)) { + throw new IllegalStateException("Method " + method.getReference() + " was marked with " + + MetadataProvider.class.getName() + " but it is not native"); + } + } +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/MetadataProviderTransformer.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/MetadataProviderTransformer.java new file mode 100644 index 000000000..703052af3 --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/MetadataProviderTransformer.java @@ -0,0 +1,39 @@ +/* + * 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.javascript.ni.GeneratedBy; +import org.teavm.model.*; +import org.teavm.platform.metadata.MetadataProvider; + +/** + * + * @author Alexey Andreev + */ +class MetadataProviderTransformer implements ClassHolderTransformer { + @Override + public void transformClass(ClassHolder cls, ClassReaderSource innerSource) { + for (MethodHolder method : cls.getMethods()) { + AnnotationReader providerAnnot = method.getAnnotations().get(MetadataProvider.class.getName()); + if (providerAnnot == null) { + return; + } + AnnotationHolder genAnnot = new AnnotationHolder(GeneratedBy.class.getName()); + genAnnot.getValues().put("value", new AnnotationValue(ValueType.object(null))); + method.getAnnotations().add(genAnnot); + } + } +} 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 327e6f66f..6589f4c8b 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 @@ -25,5 +25,6 @@ import org.teavm.vm.spi.TeaVMPlugin; public class PlatformPlugin implements TeaVMPlugin { @Override public void install(TeaVMHost host) { + host.add(new MetadataProviderTransformer()); } } diff --git a/teavm-platform/src/test/java/org/teavm/platform/metadata/MetadataGeneratorTest.java b/teavm-platform/src/test/java/org/teavm/platform/metadata/MetadataGeneratorTest.java new file mode 100644 index 000000000..4f240dd36 --- /dev/null +++ b/teavm-platform/src/test/java/org/teavm/platform/metadata/MetadataGeneratorTest.java @@ -0,0 +1,24 @@ +/* + * 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.metadata; + +/** + * + * @author Alexey Andreev + */ +public class MetadataGeneratorTest { + +} diff --git a/teavm-platform/src/test/java/org/teavm/platform/metadata/TestResource.java b/teavm-platform/src/test/java/org/teavm/platform/metadata/TestResource.java new file mode 100644 index 000000000..d75474deb --- /dev/null +++ b/teavm-platform/src/test/java/org/teavm/platform/metadata/TestResource.java @@ -0,0 +1,31 @@ +/* + * 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.metadata; + +/** + * + * @author Alexey Andreev + */ +@Resource +public interface TestResource { + int getInt(); + + void setInt(int value); + + String getString(); + + void setString(String string); +}