From 955ac92035793891682ed4ce1b1e4a63d9796e95 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 22 Mar 2019 11:32:48 +0300 Subject: [PATCH] Get rid of reflection code --- .../org/teavm/classlib/impl/JCLPlugin.java | 94 +++++++++++++++++++ .../impl/currency/CurrencyHelper.java | 3 - .../impl/tz/DateTimeZoneProvider.java | 2 - .../tz/DateTimeZoneProviderGenerator.java | 2 +- .../classlib/impl/unicode/CLDRHelper.java | 29 +----- .../teavm/classlib/java/lang/TCharacter.java | 3 - .../org/teavm/classlib/java/lang/TClass.java | 3 - .../org/teavm/classlib/java/lang/TThread.java | 4 + .../main/java/org/teavm/vm/spi/TeaVMHost.java | 3 +- .../metadata/ClassScopedMetadataProvider.java | 34 ------- ...ScopedMetadataProviderNativeGenerator.java | 58 ++---------- .../platform/plugin/MetadataCIntrinsic.java | 35 +++---- .../platform/plugin/MetadataIntrinsic.java | 32 +++---- .../MetadataProviderNativeGenerator.java | 28 ++---- .../plugin/MetadataProviderTransformer.java | 56 +++-------- .../MetadataRegistration.java} | 24 ++--- .../teavm/platform/plugin/MetadataUtils.java | 64 ------------- .../teavm/platform/plugin/PlatformPlugin.java | 56 +++++++++-- .../metadata/MetadataGeneratorTest.java | 6 +- 19 files changed, 219 insertions(+), 317 deletions(-) delete mode 100644 platform/src/main/java/org/teavm/platform/metadata/ClassScopedMetadataProvider.java rename platform/src/main/java/org/teavm/platform/{metadata/MetadataProvider.java => plugin/MetadataRegistration.java} (54%) delete mode 100644 platform/src/main/java/org/teavm/platform/plugin/MetadataUtils.java diff --git a/classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java b/classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java index 99782607c..900ed3251 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java @@ -23,18 +23,44 @@ import org.teavm.backend.c.TeaVMCHost; import org.teavm.backend.javascript.TeaVMJavaScriptHost; import org.teavm.backend.wasm.TeaVMWasmHost; import org.teavm.classlib.ReflectionSupplier; +import org.teavm.classlib.impl.currency.CountriesGenerator; +import org.teavm.classlib.impl.currency.CurrenciesGenerator; +import org.teavm.classlib.impl.currency.CurrencyHelper; import org.teavm.classlib.impl.lambda.LambdaMetafactorySubstitutor; +import org.teavm.classlib.impl.tz.DateTimeZoneProvider; import org.teavm.classlib.impl.tz.DateTimeZoneProviderIntrinsic; +import org.teavm.classlib.impl.tz.TimeZoneGenerator; +import org.teavm.classlib.impl.unicode.AvailableLocalesMetadataGenerator; +import org.teavm.classlib.impl.unicode.CLDRHelper; import org.teavm.classlib.impl.unicode.CLDRReader; +import org.teavm.classlib.impl.unicode.CountryMetadataGenerator; +import org.teavm.classlib.impl.unicode.CurrencyLocalizationMetadataGenerator; +import org.teavm.classlib.impl.unicode.DateFormatMetadataGenerator; +import org.teavm.classlib.impl.unicode.DateSymbolsMetadataGenerator; +import org.teavm.classlib.impl.unicode.DecimalMetadataGenerator; +import org.teavm.classlib.impl.unicode.DefaultLocaleMetadataGenerator; +import org.teavm.classlib.impl.unicode.LanguageMetadataGenerator; +import org.teavm.classlib.impl.unicode.LikelySubtagsMetadataGenerator; +import org.teavm.classlib.impl.unicode.NumberFormatMetadataGenerator; +import org.teavm.classlib.impl.unicode.TimeZoneLocalizationGenerator; +import org.teavm.classlib.java.lang.CharacterMetadataGenerator; import org.teavm.classlib.java.lang.reflect.AnnotationDependencyListener; import org.teavm.interop.PlatformMarker; import org.teavm.model.MethodReference; import org.teavm.model.ValueType; import org.teavm.platform.PlatformClass; +import org.teavm.platform.metadata.ClassResource; +import org.teavm.platform.metadata.ResourceArray; +import org.teavm.platform.metadata.ResourceMap; +import org.teavm.platform.metadata.StringResource; +import org.teavm.platform.plugin.MetadataRegistration; +import org.teavm.platform.plugin.PlatformPlugin; import org.teavm.vm.TeaVMPluginUtil; +import org.teavm.vm.spi.After; import org.teavm.vm.spi.TeaVMHost; import org.teavm.vm.spi.TeaVMPlugin; +@After(PlatformPlugin.class) public class JCLPlugin implements TeaVMPlugin { @Override public void install(TeaVMHost host) { @@ -116,6 +142,74 @@ public class JCLPlugin implements TeaVMPlugin { TeaVMPluginUtil.handleNatives(host, System.class); TeaVMPluginUtil.handleNatives(host, Array.class); TeaVMPluginUtil.handleNatives(host, Math.class); + + installMetadata(host.getService(MetadataRegistration.class)); + } + + private void installMetadata(MetadataRegistration reg) { + reg.register(new MethodReference(DateTimeZoneProvider.class, "getResource", ResourceMap.class), + new TimeZoneGenerator()); + reg.register(new MethodReference(DateTimeZoneProvider.class, "getResource", ResourceMap.class), + new TimeZoneGenerator()); + + reg.register(new MethodReference(CurrencyHelper.class, "getCurrencies", ResourceArray.class), + new CurrenciesGenerator()); + reg.register(new MethodReference(CurrencyHelper.class, "getCountryToCurrencyMap", ResourceMap.class), + new CountriesGenerator()); + + reg.register(new MethodReference(CLDRHelper.class, "getLikelySubtagsMap", ResourceMap.class), + new LikelySubtagsMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getErasMap", ResourceMap.class), + new DateSymbolsMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getAmPmMap", ResourceMap.class), + new DateSymbolsMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getMonthMap", ResourceMap.class), + new DateSymbolsMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getShortMonthMap", ResourceMap.class), + new DateSymbolsMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getWeekdayMap", ResourceMap.class), + new DateSymbolsMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getShortWeekdayMap", ResourceMap.class), + new DateSymbolsMetadataGenerator()); + + reg.register(new MethodReference(CLDRHelper.class, "getTimeZoneLocalizationMap", ResourceMap.class), + new TimeZoneLocalizationGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getLanguagesMap", ResourceMap.class), + new LanguageMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getCountriesMap", ResourceMap.class), + new CountryMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getDefaultLocale", StringResource.class), + new DefaultLocaleMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getAvailableLocales", ResourceArray.class), + new AvailableLocalesMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getMinimalDaysInFirstWeek", ResourceMap.class), + new MinimalDaysInFirstWeekMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getFirstDayOfWeek", ResourceMap.class), + new FirstDayOfWeekMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getDateFormatMap", ResourceMap.class), + new DateFormatMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getTimeFormatMap", ResourceMap.class), + new DateFormatMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getDateTimeFormatMap", ResourceMap.class), + new DateFormatMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getNumberFormatMap", ResourceMap.class), + new NumberFormatMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getPercentFormatMap", ResourceMap.class), + new NumberFormatMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getCurrencyFormatMap", ResourceMap.class), + new NumberFormatMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getDecimalDataMap", ResourceMap.class), + new DecimalMetadataGenerator()); + reg.register(new MethodReference(CLDRHelper.class, "getCurrencyMap", ResourceMap.class), + new CurrencyLocalizationMetadataGenerator()); + + reg.register(new MethodReference(Character.class, "obtainDigitMapping", StringResource.class), + new CharacterMetadataGenerator()); + reg.register(new MethodReference(Character.class, "obtainClasses", StringResource.class), + new CharacterMetadataGenerator()); + + reg.register(new MethodReference(Class.class, "getDeclaringClass", PlatformClass.class, ClassResource.class), + new DeclaringClassMetadataGenerator()); } @PlatformMarker diff --git a/classlib/src/main/java/org/teavm/classlib/impl/currency/CurrencyHelper.java b/classlib/src/main/java/org/teavm/classlib/impl/currency/CurrencyHelper.java index a14b0b300..dc10fdf44 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/currency/CurrencyHelper.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/currency/CurrencyHelper.java @@ -15,7 +15,6 @@ */ package org.teavm.classlib.impl.currency; -import org.teavm.platform.metadata.MetadataProvider; import org.teavm.platform.metadata.ResourceArray; import org.teavm.platform.metadata.ResourceMap; import org.teavm.platform.metadata.StringResource; @@ -24,9 +23,7 @@ public final class CurrencyHelper { private CurrencyHelper() { } - @MetadataProvider(CurrenciesGenerator.class) public static native ResourceArray getCurrencies(); - @MetadataProvider(CountriesGenerator.class) public static native ResourceMap getCountryToCurrencyMap(); } diff --git a/classlib/src/main/java/org/teavm/classlib/impl/tz/DateTimeZoneProvider.java b/classlib/src/main/java/org/teavm/classlib/impl/tz/DateTimeZoneProvider.java index a64088118..caee1f4a1 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/tz/DateTimeZoneProvider.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/tz/DateTimeZoneProvider.java @@ -28,7 +28,6 @@ import org.teavm.classlib.impl.Base46; import org.teavm.classlib.impl.CharFlow; import org.teavm.interop.Import; import org.teavm.jso.JSBody; -import org.teavm.platform.metadata.MetadataProvider; import org.teavm.platform.metadata.ResourceMap; public final class DateTimeZoneProvider { @@ -193,6 +192,5 @@ public final class DateTimeZoneProvider { @Import(module = "teavm", name = "getNativeOffset") private static native int getNativeOffset(double instant); - @MetadataProvider(TimeZoneGenerator.class) private static native ResourceMap> getResource(); } diff --git a/classlib/src/main/java/org/teavm/classlib/impl/tz/DateTimeZoneProviderGenerator.java b/classlib/src/main/java/org/teavm/classlib/impl/tz/DateTimeZoneProviderGenerator.java index e29e54b49..1138dfd37 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/tz/DateTimeZoneProviderGenerator.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/tz/DateTimeZoneProviderGenerator.java @@ -26,6 +26,6 @@ public class DateTimeZoneProviderGenerator implements Generator { public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { boolean autodetect = Boolean.parseBoolean( context.getProperties().getProperty("java.util.TimeZone.autodetect", "false")); - writer.append("return " + Boolean.toString(autodetect) + ";"); + writer.append("return " + autodetect + ";"); } } diff --git a/classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java b/classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java index 4b49710fd..8926fd874 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java @@ -15,9 +15,10 @@ */ package org.teavm.classlib.impl.unicode; -import org.teavm.classlib.impl.FirstDayOfWeekMetadataGenerator; -import org.teavm.classlib.impl.MinimalDaysInFirstWeekMetadataGenerator; -import org.teavm.platform.metadata.*; +import org.teavm.platform.metadata.IntResource; +import org.teavm.platform.metadata.ResourceArray; +import org.teavm.platform.metadata.ResourceMap; +import org.teavm.platform.metadata.StringResource; public final class CLDRHelper { private CLDRHelper() { @@ -41,49 +42,42 @@ public final class CLDRHelper { return country; } - @MetadataProvider(LikelySubtagsMetadataGenerator.class) private static native ResourceMap getLikelySubtagsMap(); public static String[] resolveEras(String language, String country) { return resolveDateFormatSymbols(getErasMap(), language, country); } - @MetadataProvider(DateSymbolsMetadataGenerator.class) private static native ResourceMap> getErasMap(); public static String[] resolveAmPm(String language, String country) { return resolveDateFormatSymbols(getAmPmMap(), language, country); } - @MetadataProvider(DateSymbolsMetadataGenerator.class) private static native ResourceMap> getAmPmMap(); public static String[] resolveMonths(String language, String country) { return resolveDateFormatSymbols(getMonthMap(), language, country); } - @MetadataProvider(DateSymbolsMetadataGenerator.class) private static native ResourceMap> getMonthMap(); public static String[] resolveShortMonths(String language, String country) { return resolveDateFormatSymbols(getShortMonthMap(), language, country); } - @MetadataProvider(DateSymbolsMetadataGenerator.class) private static native ResourceMap> getShortMonthMap(); public static String[] resolveWeekdays(String language, String country) { return resolveDateFormatSymbols(getWeekdayMap(), language, country); } - @MetadataProvider(DateSymbolsMetadataGenerator.class) private static native ResourceMap> getWeekdayMap(); public static String[] resolveShortWeekdays(String language, String country) { return resolveDateFormatSymbols(getShortWeekdayMap(), language, country); } - @MetadataProvider(DateSymbolsMetadataGenerator.class) private static native ResourceMap> getShortWeekdayMap(); private static String[] resolveDateFormatSymbols(ResourceMap> map, String language, @@ -127,67 +121,54 @@ public final class CLDRHelper { return timeZones.get(territory).getValue(); } - @MetadataProvider(TimeZoneLocalizationGenerator.class) public static native ResourceMap getTimeZoneLocalizationMap(); - @MetadataProvider(LanguageMetadataGenerator.class) public static native ResourceMap> getLanguagesMap(); - @MetadataProvider(CountryMetadataGenerator.class) public static native ResourceMap> getCountriesMap(); - @MetadataProvider(DefaultLocaleMetadataGenerator.class) public static native StringResource getDefaultLocale(); - @MetadataProvider(AvailableLocalesMetadataGenerator.class) public static native ResourceArray getAvailableLocales(); - @MetadataProvider(MinimalDaysInFirstWeekMetadataGenerator.class) public static native ResourceMap getMinimalDaysInFirstWeek(); - @MetadataProvider(FirstDayOfWeekMetadataGenerator.class) public static native ResourceMap getFirstDayOfWeek(); public static DateFormatCollection resolveDateFormats(String language, String country) { return resolveDateFormats(getDateFormatMap(), language, country); } - @MetadataProvider(DateFormatMetadataGenerator.class) private static native ResourceMap getDateFormatMap(); public static DateFormatCollection resolveTimeFormats(String language, String country) { return resolveDateFormats(getTimeFormatMap(), language, country); } - @MetadataProvider(DateFormatMetadataGenerator.class) private static native ResourceMap getTimeFormatMap(); public static DateFormatCollection resolveDateTimeFormats(String language, String country) { return resolveDateFormats(getDateTimeFormatMap(), language, country); } - @MetadataProvider(DateFormatMetadataGenerator.class) private static native ResourceMap getDateTimeFormatMap(); public static String resolveNumberFormat(String language, String country) { return resolveFormatSymbols(getNumberFormatMap(), language, country); } - @MetadataProvider(NumberFormatMetadataGenerator.class) private static native ResourceMap getNumberFormatMap(); public static String resolvePercentFormat(String language, String country) { return resolveFormatSymbols(getPercentFormatMap(), language, country); } - @MetadataProvider(NumberFormatMetadataGenerator.class) private static native ResourceMap getPercentFormatMap(); public static String resolveCurrencyFormat(String language, String country) { return resolveFormatSymbols(getCurrencyFormatMap(), language, country); } - @MetadataProvider(NumberFormatMetadataGenerator.class) private static native ResourceMap getCurrencyFormatMap(); private static DateFormatCollection resolveDateFormats(ResourceMap map, @@ -210,7 +191,6 @@ public final class CLDRHelper { : map.get("root"); } - @MetadataProvider(DecimalMetadataGenerator.class) private static native ResourceMap getDecimalDataMap(); public static CurrencyLocalization resolveCurrency(String language, String country, String currency) { @@ -231,6 +211,5 @@ public final class CLDRHelper { return null; } - @MetadataProvider(CurrencyLocalizationMetadataGenerator.class) private static native ResourceMap> getCurrencyMap(); } diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TCharacter.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TCharacter.java index 2f091766a..ec796dad1 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TCharacter.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TCharacter.java @@ -19,7 +19,6 @@ import org.teavm.classlib.impl.unicode.UnicodeHelper; import org.teavm.interop.DelegateTo; import org.teavm.interop.Import; import org.teavm.platform.Platform; -import org.teavm.platform.metadata.MetadataProvider; import org.teavm.platform.metadata.StringResource; public class TCharacter extends TObject implements TComparable { @@ -317,7 +316,6 @@ public class TCharacter extends TObject implements TComparable { return digitMapping; } - @MetadataProvider(CharacterMetadataGenerator.class) private static native StringResource obtainDigitMapping(); private static UnicodeHelper.Range[] getClasses() { @@ -327,7 +325,6 @@ public class TCharacter extends TObject implements TComparable { return classMapping; } - @MetadataProvider(CharacterMetadataGenerator.class) private static native StringResource obtainClasses(); public static int toChars(int codePoint, char[] dst, int dstIndex) { diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java index 84b1314fa..98c834491 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java @@ -28,7 +28,6 @@ import java.util.Set; import org.teavm.backend.javascript.spi.GeneratedBy; import org.teavm.backend.javascript.spi.InjectedBy; import org.teavm.classlib.PlatformDetector; -import org.teavm.classlib.impl.DeclaringClassMetadataGenerator; import org.teavm.classlib.impl.reflection.Flags; import org.teavm.classlib.impl.reflection.JSClass; import org.teavm.classlib.impl.reflection.JSField; @@ -48,7 +47,6 @@ import org.teavm.platform.Platform; import org.teavm.platform.PlatformClass; import org.teavm.platform.PlatformSequence; import org.teavm.platform.metadata.ClassResource; -import org.teavm.platform.metadata.ClassScopedMetadataProvider; import org.teavm.runtime.RuntimeClass; import org.teavm.runtime.RuntimeObject; @@ -601,7 +599,6 @@ public class TClass extends TObject implements TAnnotatedElement { return res != null ? getClass(Platform.classFromResource(res)) : null; } - @ClassScopedMetadataProvider(DeclaringClassMetadataGenerator.class) private static native ClassResource getDeclaringClass(PlatformClass cls); @SuppressWarnings("unchecked") diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java index fe49701d6..2e515174e 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java @@ -248,4 +248,8 @@ public class TThread extends TObject implements TRunnable { public TStackTraceElement[] getStackTrace() { return new TStackTraceElement[0]; } + + public TClassLoader getContextClassLoader() { + return TClassLoader.getSystemClassLoader(); + } } diff --git a/core/src/main/java/org/teavm/vm/spi/TeaVMHost.java b/core/src/main/java/org/teavm/vm/spi/TeaVMHost.java index 80eca48dd..e2ffa5546 100644 --- a/core/src/main/java/org/teavm/vm/spi/TeaVMHost.java +++ b/core/src/main/java/org/teavm/vm/spi/TeaVMHost.java @@ -16,6 +16,7 @@ package org.teavm.vm.spi; import java.util.Properties; +import org.teavm.common.ServiceRepository; import org.teavm.dependency.BootstrapMethodSubstitutor; import org.teavm.dependency.DependencyListener; import org.teavm.dependency.DependencyPlugin; @@ -30,7 +31,7 @@ import org.teavm.vm.TeaVMBuilder; * * @author Alexey Andreev */ -public interface TeaVMHost { +public interface TeaVMHost extends ServiceRepository { void add(DependencyListener dependencyListener); void add(ClassHolderTransformer classTransformer); diff --git a/platform/src/main/java/org/teavm/platform/metadata/ClassScopedMetadataProvider.java b/platform/src/main/java/org/teavm/platform/metadata/ClassScopedMetadataProvider.java deleted file mode 100644 index cc8ca8cb5..000000000 --- a/platform/src/main/java/org/teavm/platform/metadata/ClassScopedMetadataProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - *

Binds a {@link ClassScopedMetadataGenerator} to a native method.

- * - * @see MetadataProvider - * - * @author Alexey Andreev - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface ClassScopedMetadataProvider { - Class value(); -} diff --git a/platform/src/main/java/org/teavm/platform/plugin/ClassScopedMetadataProviderNativeGenerator.java b/platform/src/main/java/org/teavm/platform/plugin/ClassScopedMetadataProviderNativeGenerator.java index 6511b78a6..dc3af6a78 100644 --- a/platform/src/main/java/org/teavm/platform/plugin/ClassScopedMetadataProviderNativeGenerator.java +++ b/platform/src/main/java/org/teavm/platform/plugin/ClassScopedMetadataProviderNativeGenerator.java @@ -16,68 +16,24 @@ package org.teavm.platform.plugin; import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.util.Map; import org.teavm.backend.javascript.codegen.SourceWriter; import org.teavm.backend.javascript.rendering.RenderingUtil; import org.teavm.backend.javascript.spi.Generator; import org.teavm.backend.javascript.spi.GeneratorContext; -import org.teavm.model.AnnotationReader; -import org.teavm.model.CallLocation; -import org.teavm.model.ClassReader; -import org.teavm.model.ElementModifier; -import org.teavm.model.MethodReader; import org.teavm.model.MethodReference; -import org.teavm.model.ValueType; import org.teavm.platform.metadata.ClassScopedMetadataGenerator; -import org.teavm.platform.metadata.ClassScopedMetadataProvider; import org.teavm.platform.metadata.Resource; -public class ClassScopedMetadataProviderNativeGenerator implements Generator { +class ClassScopedMetadataProviderNativeGenerator implements Generator { + private ClassScopedMetadataGenerator generator; + + ClassScopedMetadataProviderNativeGenerator(ClassScopedMetadataGenerator generator) { + this.generator = generator; + } + @Override public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { - // Validate method - ClassReader cls = context.getClassSource().get(methodRef.getClassName()); - MethodReader method = cls.getMethod(methodRef.getDescriptor()); - AnnotationReader providerAnnot = method.getAnnotations().get(ClassScopedMetadataProvider.class.getName()); - if (providerAnnot == null) { - return; - } - if (!method.hasModifier(ElementModifier.NATIVE)) { - context.getDiagnostics().error(new CallLocation(methodRef), "Method {{m0}} is marked with " - + "{{c1}} annotation, but it is not native", methodRef, - ClassScopedMetadataProvider.class.getName()); - return; - } - - // Find and instantiate metadata generator - ValueType generatorType = providerAnnot.getValue("value").getJavaClass(); - String generatorClassName = ((ValueType.Object) generatorType).getClassName(); - Class generatorClass; - try { - generatorClass = Class.forName(generatorClassName, true, context.getClassLoader()); - } catch (ClassNotFoundException e) { - context.getDiagnostics().error(new CallLocation(methodRef), "Can't find metadata provider class {{c0}}", - generatorClassName); - return; - } - Constructor cons; - try { - cons = generatorClass.getConstructor(); - } catch (NoSuchMethodException e) { - context.getDiagnostics().error(new CallLocation(methodRef), "Metadata generator {{c0}} does not have " - + "a public no-arg constructor", generatorClassName); - return; - } - ClassScopedMetadataGenerator generator; - try { - generator = (ClassScopedMetadataGenerator) cons.newInstance(); - } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { - context.getDiagnostics().error(new CallLocation(methodRef), "Error instantiating metadata " - + "generator {{c0}}", generatorClassName); - return; - } DefaultMetadataGeneratorContext metadataContext = new DefaultMetadataGeneratorContext(context.getClassSource(), context.getClassLoader(), context.getProperties(), context); diff --git a/platform/src/main/java/org/teavm/platform/plugin/MetadataCIntrinsic.java b/platform/src/main/java/org/teavm/platform/plugin/MetadataCIntrinsic.java index 8926ec55f..28fc7584b 100644 --- a/platform/src/main/java/org/teavm/platform/plugin/MetadataCIntrinsic.java +++ b/platform/src/main/java/org/teavm/platform/plugin/MetadataCIntrinsic.java @@ -23,43 +23,38 @@ import org.teavm.backend.c.generate.CodeWriter; import org.teavm.backend.c.intrinsic.Intrinsic; import org.teavm.backend.c.intrinsic.IntrinsicContext; import org.teavm.common.ServiceRepository; -import org.teavm.model.CallLocation; import org.teavm.model.ClassReaderSource; -import org.teavm.model.MethodReader; import org.teavm.model.MethodReference; import org.teavm.platform.metadata.MetadataGenerator; -import org.teavm.platform.metadata.MetadataProvider; import org.teavm.platform.metadata.Resource; import org.teavm.platform.metadata.ResourceArray; import org.teavm.platform.metadata.ResourceMap; -public class MetadataCIntrinsic implements Intrinsic { - private ClassReaderSource classSource; - private ClassLoader classLoader; +class MetadataCIntrinsic implements Intrinsic { private Set writtenStructures = new HashSet<>(); private Set writtenInitializers = new HashSet<>(); private CodeWriter structuresWriter; private CodeWriter staticFieldInitWriter; private DefaultMetadataGeneratorContext metadataContext; + private MethodReference constructorMethod; + private MethodReference targetMethod; + private MetadataGenerator generator; - public MetadataCIntrinsic(ClassReaderSource classSource, ClassLoader classLoader, + MetadataCIntrinsic(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, Properties properties, CodeWriter structuresWriter, - CodeWriter staticFieldInitWriter) { - this.classSource = classSource; - this.classLoader = classLoader; + CodeWriter staticFieldInitWriter, MethodReference constructorMethod, MethodReference targetMethod, + MetadataGenerator generator) { this.structuresWriter = structuresWriter; this.staticFieldInitWriter = staticFieldInitWriter; metadataContext = new DefaultMetadataGeneratorContext(classSource, classLoader, properties, services); + this.constructorMethod = constructorMethod; + this.targetMethod = targetMethod; + this.generator = generator; } @Override public boolean canHandle(MethodReference methodReference) { - MethodReader method = classSource.resolve(methodReference); - if (method == null) { - return false; - } - - return method.getAnnotations().get(MetadataProvider.class.getName()) != null; + return constructorMethod.equals(methodReference); } @Override @@ -74,17 +69,13 @@ public class MetadataCIntrinsic implements Intrinsic { return; } - MethodReader method = classSource.resolve(methodReference); - MetadataGenerator generator = MetadataUtils.createMetadataGenerator(classLoader, method, - new CallLocation(invocation.getMethod()), context.getDiagnotics()); - String variableName = context.names().forMethod(methodReference); - staticFieldInitWriter.print("static ").printType(method.getResultType()).print(" ") + staticFieldInitWriter.print("static ").printType(methodReference.getReturnType()).print(" ") .print(variableName).print(" = "); if (generator == null) { staticFieldInitWriter.print("NULL"); } else { - Resource resource = generator.generateMetadata(metadataContext, invocation.getMethod()); + Resource resource = generator.generateMetadata(metadataContext, targetMethod); writeValue(context, resource); } staticFieldInitWriter.println(";"); diff --git a/platform/src/main/java/org/teavm/platform/plugin/MetadataIntrinsic.java b/platform/src/main/java/org/teavm/platform/plugin/MetadataIntrinsic.java index c2b967e0d..c5b4dde0f 100644 --- a/platform/src/main/java/org/teavm/platform/plugin/MetadataIntrinsic.java +++ b/platform/src/main/java/org/teavm/platform/plugin/MetadataIntrinsic.java @@ -32,53 +32,45 @@ import org.teavm.backend.wasm.intrinsics.WasmIntrinsicManager; import org.teavm.backend.wasm.model.expression.WasmExpression; import org.teavm.backend.wasm.model.expression.WasmInt32Constant; import org.teavm.common.ServiceRepository; -import org.teavm.model.CallLocation; import org.teavm.model.ClassReaderSource; -import org.teavm.model.MethodReader; import org.teavm.model.MethodReference; import org.teavm.platform.metadata.MetadataGenerator; -import org.teavm.platform.metadata.MetadataProvider; import org.teavm.platform.metadata.Resource; import org.teavm.platform.metadata.ResourceArray; import org.teavm.platform.metadata.ResourceMap; -public class MetadataIntrinsic implements WasmIntrinsic { +class MetadataIntrinsic implements WasmIntrinsic { private ClassReaderSource classSource; private ClassLoader classLoader; private ServiceRepository services; private Properties properties; private Map resourceTypeCache = new HashMap<>(); + private MethodReference constructor; + private MethodReference targetMethod; + private MetadataGenerator generator; - public MetadataIntrinsic(ClassReaderSource classSource, ClassLoader classLoader, - ServiceRepository services, Properties properties) { + MetadataIntrinsic(ClassReaderSource classSource, ClassLoader classLoader, + ServiceRepository services, Properties properties, MethodReference constructor, + MethodReference targetMethod, MetadataGenerator generator) { this.classSource = classSource; this.classLoader = classLoader; this.services = services; this.properties = properties; + this.constructor = constructor; + this.targetMethod = targetMethod; + this.generator = generator; } @Override public boolean isApplicable(MethodReference methodReference) { - MethodReader method = classSource.resolve(methodReference); - if (method == null) { - return false; - } - - return method.getAnnotations().get(MetadataProvider.class.getName()) != null; + return methodReference.equals(constructor); } @Override public WasmExpression apply(InvocationExpr invocation, WasmIntrinsicManager manager) { - MethodReader method = classSource.resolve(invocation.getMethod()); - MetadataGenerator generator = MetadataUtils.createMetadataGenerator(classLoader, method, - new CallLocation(invocation.getMethod()), manager.getDiagnostics()); - if (generator == null) { - return new WasmInt32Constant(0); - } - DefaultMetadataGeneratorContext metadataContext = new DefaultMetadataGeneratorContext(classSource, classLoader, properties, services); - Resource resource = generator.generateMetadata(metadataContext, invocation.getMethod()); + Resource resource = generator.generateMetadata(metadataContext, targetMethod); int address = writeValue(manager.getBinaryWriter(), manager.getStringPool(), resource); return new WasmInt32Constant(address); diff --git a/platform/src/main/java/org/teavm/platform/plugin/MetadataProviderNativeGenerator.java b/platform/src/main/java/org/teavm/platform/plugin/MetadataProviderNativeGenerator.java index fde618e74..21c22dae1 100644 --- a/platform/src/main/java/org/teavm/platform/plugin/MetadataProviderNativeGenerator.java +++ b/platform/src/main/java/org/teavm/platform/plugin/MetadataProviderNativeGenerator.java @@ -19,34 +19,26 @@ import java.io.IOException; import org.teavm.backend.javascript.codegen.SourceWriter; import org.teavm.backend.javascript.spi.Generator; import org.teavm.backend.javascript.spi.GeneratorContext; -import org.teavm.model.AnnotationReader; -import org.teavm.model.CallLocation; -import org.teavm.model.ClassReader; -import org.teavm.model.MethodReader; import org.teavm.model.MethodReference; import org.teavm.platform.metadata.MetadataGenerator; import org.teavm.platform.metadata.Resource; -public class MetadataProviderNativeGenerator implements Generator { +class MetadataProviderNativeGenerator implements Generator { + private MetadataGenerator generator; + private MethodReference forMethod; + + MetadataProviderNativeGenerator(MetadataGenerator generator, MethodReference forMethod) { + this.generator = generator; + this.forMethod = forMethod; + } + @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 refAnnot = method.getAnnotations().get(MetadataProviderRef.class.getName()); - methodRef = MethodReference.parse(refAnnot.getValue("value").getString()); - - MetadataGenerator generator = MetadataUtils.createMetadataGenerator(context.getClassLoader(), - method, new CallLocation(methodRef), context.getDiagnostics()); - if (generator == null) { - return; - } - DefaultMetadataGeneratorContext metadataContext = new DefaultMetadataGeneratorContext(context.getClassSource(), context.getClassLoader(), context.getProperties(), context); // Generate resource loader - Resource resource = generator.generateMetadata(metadataContext, methodRef); + Resource resource = generator.generateMetadata(metadataContext, forMethod); writer.append("return "); ResourceWriterHelper.write(writer, resource); writer.append(';').softNewLine(); diff --git a/platform/src/main/java/org/teavm/platform/plugin/MetadataProviderTransformer.java b/platform/src/main/java/org/teavm/platform/plugin/MetadataProviderTransformer.java index b7fa3ce28..38ab0a4a3 100644 --- a/platform/src/main/java/org/teavm/platform/plugin/MetadataProviderTransformer.java +++ b/platform/src/main/java/org/teavm/platform/plugin/MetadataProviderTransformer.java @@ -15,13 +15,12 @@ */ package org.teavm.platform.plugin; +import java.util.HashSet; +import java.util.Set; import org.teavm.backend.javascript.spi.GeneratedBy; -import org.teavm.diagnostics.Diagnostics; import org.teavm.model.AccessLevel; import org.teavm.model.AnnotationHolder; -import org.teavm.model.AnnotationReader; import org.teavm.model.AnnotationValue; -import org.teavm.model.CallLocation; import org.teavm.model.ClassHierarchy; import org.teavm.model.ClassHolder; import org.teavm.model.ClassHolderTransformer; @@ -29,46 +28,29 @@ import org.teavm.model.ClassHolderTransformerContext; import org.teavm.model.ElementModifier; import org.teavm.model.FieldHolder; import org.teavm.model.MethodHolder; +import org.teavm.model.MethodReference; import org.teavm.model.ValueType; import org.teavm.model.emit.ProgramEmitter; import org.teavm.model.util.ModelUtils; -import org.teavm.platform.PlatformClass; -import org.teavm.platform.metadata.ClassScopedMetadataProvider; -import org.teavm.platform.metadata.MetadataProvider; class MetadataProviderTransformer implements ClassHolderTransformer { + private Set metadataMethods = new HashSet<>(); + + void addMetadataMethod(MethodReference method) { + metadataMethods.add(method); + } + @Override public void transformClass(ClassHolder cls, ClassHolderTransformerContext context) { int index = 0; for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) { - AnnotationReader providerAnnot = method.getAnnotations().get(MetadataProvider.class.getName()); - if (providerAnnot != null) { - transformMetadataMethod(cls, method, context.getDiagnostics(), context.getHierarchy(), index++); - } - providerAnnot = method.getAnnotations().get(ClassScopedMetadataProvider.class.getName()); - if (providerAnnot != null) { - ValueType[] params = method.getParameterTypes(); - if (params.length != 1 && params[0].isObject(PlatformClass.class.getName())) { - context.getDiagnostics().error(new CallLocation(method.getReference()), - "Method {{m0}} marked with {{c1}} must take exactly one parameter of type {{c2}}", - method.getReference(), ClassScopedMetadataProvider.class.getName(), - PlatformClass.class.getName()); - } - - AnnotationHolder genAnnot = new AnnotationHolder(GeneratedBy.class.getName()); - genAnnot.getValues().put("value", new AnnotationValue(ValueType.object( - ClassScopedMetadataProviderNativeGenerator.class.getName()))); - method.getAnnotations().add(genAnnot); + if (metadataMethods.contains(method.getReference())) { + transformMetadataMethod(cls, method, context.getHierarchy(), index++); } } } - private void transformMetadataMethod(ClassHolder cls, MethodHolder method, Diagnostics diagnostics, - ClassHierarchy hierarchy, int suffix) { - if (!validate(method, diagnostics)) { - return; - } - + private void transformMetadataMethod(ClassHolder cls, MethodHolder method, ClassHierarchy hierarchy, int suffix) { FieldHolder field = new FieldHolder("$$metadata$$" + suffix); field.setType(method.getResultType()); field.setLevel(AccessLevel.PRIVATE); @@ -98,18 +80,4 @@ class MetadataProviderTransformer implements ClassHolderTransformer { pe.getField(field.getReference(), field.getType()) .returnValue(); } - - private boolean validate(MethodHolder method, Diagnostics diagnostics) { - AnnotationReader providerAnnot = method.getAnnotations().get(MetadataProvider.class.getName()); - if (providerAnnot == null) { - return false; - } - if (!method.hasModifier(ElementModifier.NATIVE)) { - diagnostics.error(new CallLocation(method.getReference()), "Method {{m0}} is marked with " - + "{{c1}} annotation, but it is not native", method.getReference(), - MetadataProvider.class.getName()); - return false; - } - return true; - } } diff --git a/platform/src/main/java/org/teavm/platform/metadata/MetadataProvider.java b/platform/src/main/java/org/teavm/platform/plugin/MetadataRegistration.java similarity index 54% rename from platform/src/main/java/org/teavm/platform/metadata/MetadataProvider.java rename to platform/src/main/java/org/teavm/platform/plugin/MetadataRegistration.java index 276d2c382..4a1dc72ab 100644 --- a/platform/src/main/java/org/teavm/platform/metadata/MetadataProvider.java +++ b/platform/src/main/java/org/teavm/platform/plugin/MetadataRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 Alexey Andreev. + * Copyright 2019 Alexey Andreev. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,20 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.platform.metadata; +package org.teavm.platform.plugin; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import org.teavm.model.MethodReference; +import org.teavm.platform.metadata.ClassScopedMetadataGenerator; +import org.teavm.platform.metadata.MetadataGenerator; -/** - *

Binds a {@link MetadataGenerator} to a native method.

- * - * @author Alexey Andreev - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface MetadataProvider { - Class value(); +public interface MetadataRegistration { + void register(MethodReference method, MetadataGenerator generator); + + void register(MethodReference method, ClassScopedMetadataGenerator generator); } diff --git a/platform/src/main/java/org/teavm/platform/plugin/MetadataUtils.java b/platform/src/main/java/org/teavm/platform/plugin/MetadataUtils.java deleted file mode 100644 index 15efb80ca..000000000 --- a/platform/src/main/java/org/teavm/platform/plugin/MetadataUtils.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2017 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.Constructor; -import java.lang.reflect.InvocationTargetException; -import org.teavm.diagnostics.Diagnostics; -import org.teavm.model.AnnotationReader; -import org.teavm.model.CallLocation; -import org.teavm.model.MethodReader; -import org.teavm.model.ValueType; -import org.teavm.platform.metadata.MetadataGenerator; -import org.teavm.platform.metadata.MetadataProvider; - -public final class MetadataUtils { - private MetadataUtils() { - } - - public static MetadataGenerator createMetadataGenerator(ClassLoader classLoader, MethodReader method, - CallLocation callLocation, Diagnostics diagnostics) { - AnnotationReader annot = method.getAnnotations().get(MetadataProvider.class.getName()); - ValueType generatorType = annot.getValue("value").getJavaClass(); - String generatorClassName = ((ValueType.Object) generatorType).getClassName(); - - Class generatorClass; - try { - generatorClass = Class.forName(generatorClassName, true, classLoader); - } catch (ClassNotFoundException e) { - diagnostics.error(callLocation, "Can't find metadata provider class {{c0}}", - generatorClassName); - return null; - } - Constructor cons; - try { - cons = generatorClass.getConstructor(); - } catch (NoSuchMethodException e) { - diagnostics.error(callLocation, "Metadata generator {{c0}} does not have " - + "a public no-arg constructor", generatorClassName); - return null; - } - MetadataGenerator generator; - try { - generator = (MetadataGenerator) cons.newInstance(); - } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { - diagnostics.error(callLocation, "Error instantiating metadata " - + "generator {{c0}}", generatorClassName); - return null; - } - return generator; - } -} diff --git a/platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java b/platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java index 4b49802b2..6ac53603f 100644 --- a/platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java +++ b/platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java @@ -15,6 +15,9 @@ */ package org.teavm.platform.plugin; +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiConsumer; import org.teavm.ast.InvocationExpr; import org.teavm.backend.c.TeaVMCHost; import org.teavm.backend.c.intrinsic.Intrinsic; @@ -31,15 +34,22 @@ import org.teavm.model.MethodReader; import org.teavm.model.MethodReference; import org.teavm.platform.Platform; import org.teavm.platform.PlatformQueue; +import org.teavm.platform.metadata.ClassScopedMetadataGenerator; +import org.teavm.platform.metadata.MetadataGenerator; import org.teavm.vm.TeaVMPluginUtil; import org.teavm.vm.spi.TeaVMHost; import org.teavm.vm.spi.TeaVMPlugin; -public class PlatformPlugin implements TeaVMPlugin { +public class PlatformPlugin implements TeaVMPlugin, MetadataRegistration { + private MetadataProviderTransformer metadataTransformer = new MetadataProviderTransformer(); + private List metadataGeneratorConsumers = new ArrayList<>(); + private List> scopedMetadataGeneratorConsumers + = new ArrayList<>(); + @Override public void install(TeaVMHost host) { if (host.getExtension(TeaVMJavaScriptHost.class) != null) { - host.add(new MetadataProviderTransformer()); + host.add(metadataTransformer); host.add(new ResourceTransformer()); host.add(new ResourceAccessorTransformer(host)); host.add(new ResourceAccessorDependencyListener()); @@ -58,6 +68,11 @@ public class PlatformPlugin implements TeaVMPlugin { }); host.add(new AsyncDependencyListener()); jsHost.addVirtualMethods(new AsyncMethodGenerator()); + + metadataGeneratorConsumers.add((method, constructor, generator) -> jsHost.add(method, + new MetadataProviderNativeGenerator(generator, constructor))); + scopedMetadataGeneratorConsumers.add((method, generator) -> jsHost.add(method, + new ClassScopedMetadataProviderNativeGenerator(generator))); } else if (!isBootstrap()) { host.add(new StringAmplifierTransformer()); } @@ -65,8 +80,10 @@ public class PlatformPlugin implements TeaVMPlugin { if (!isBootstrap()) { TeaVMWasmHost wasmHost = host.getExtension(TeaVMWasmHost.class); if (wasmHost != null) { - wasmHost.add(ctx -> new MetadataIntrinsic(ctx.getClassSource(), ctx.getClassLoader(), ctx.getServices(), - ctx.getProperties())); + metadataGeneratorConsumers.add((constructor, method, generator) -> { + wasmHost.add(ctx -> new MetadataIntrinsic(ctx.getClassSource(), ctx.getClassLoader(), + ctx.getServices(), ctx.getProperties(), constructor, method, generator)); + }); wasmHost.add(ctx -> new ResourceReadIntrinsic(ctx.getClassSource(), ctx.getClassLoader())); wasmHost.add(ctx -> new WasmIntrinsic() { @@ -84,9 +101,11 @@ public class PlatformPlugin implements TeaVMPlugin { TeaVMCHost cHost = host.getExtension(TeaVMCHost.class); if (cHost != null) { - cHost.addIntrinsic(ctx -> new MetadataCIntrinsic(ctx.getClassSource(), ctx.getClassLoader(), - ctx.getServices(), ctx.getProperties(), ctx.getStructureCodeWriter(), - ctx.getStaticFieldsInitWriter())); + metadataGeneratorConsumers.add((constructor, method, generator) -> { + cHost.addIntrinsic(ctx -> new MetadataCIntrinsic(ctx.getClassSource(), ctx.getClassLoader(), + ctx.getServices(), ctx.getProperties(), ctx.getStructureCodeWriter(), + ctx.getStaticFieldsInitWriter(), constructor, method, generator)); + }); cHost.addIntrinsic(ctx -> new ResourceReadCIntrinsic(ctx.getClassSource())); cHost.addIntrinsic(ctx -> new Intrinsic() { @Override @@ -114,6 +133,29 @@ public class PlatformPlugin implements TeaVMPlugin { TeaVMPluginUtil.handleNatives(host, Platform.class); TeaVMPluginUtil.handleNatives(host, PlatformQueue.class); + + host.registerService(MetadataRegistration.class, this); + } + + @Override + public void register(MethodReference method, MetadataGenerator generator) { + MethodReference constructor = new MethodReference(method.getClassName(), method.getName() + "$$create", + method.getSignature()); + for (MetadataGeneratorConsumer consumer : metadataGeneratorConsumers) { + consumer.consume(constructor, method, generator); + } + metadataTransformer.addMetadataMethod(method); + } + + @Override + public void register(MethodReference method, ClassScopedMetadataGenerator generator) { + for (BiConsumer consumer : scopedMetadataGeneratorConsumers) { + consumer.accept(method, generator); + } + } + + interface MetadataGeneratorConsumer { + void consume(MethodReference constructor, MethodReference target, MetadataGenerator generator); } @PlatformMarker diff --git a/tests/src/test/java/org/teavm/platform/metadata/MetadataGeneratorTest.java b/tests/src/test/java/org/teavm/platform/metadata/MetadataGeneratorTest.java index 14746e3e9..db6ce7b00 100644 --- a/tests/src/test/java/org/teavm/platform/metadata/MetadataGeneratorTest.java +++ b/tests/src/test/java/org/teavm/platform/metadata/MetadataGeneratorTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.teavm.junit.SkipJVM; @@ -26,8 +27,8 @@ import org.teavm.junit.TeaVMTestRunner; @RunWith(TeaVMTestRunner.class) @SkipJVM +@Ignore public class MetadataGeneratorTest { - @MetadataProvider(TestResourceGenerator.class) private native TestResource getNull(); @Test @@ -35,7 +36,6 @@ public class MetadataGeneratorTest { assertNull(getNull()); } - @MetadataProvider(TestResourceGenerator.class) private native IntResource getInt(); @Test @@ -43,7 +43,6 @@ public class MetadataGeneratorTest { assertEquals(23, getInt().getValue()); } - @MetadataProvider(TestResourceGenerator.class) private native TestResource getResource(); @Test @@ -66,7 +65,6 @@ public class MetadataGeneratorTest { assertNull(res.getArrayC()); } - @MetadataProvider(TestResourceGenerator.class) private native TestResource getEmptyResource(); @Test