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 4c9a283a2..e3af5aa47 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java @@ -29,6 +29,7 @@ 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.DateTimeZoneProviderPatch; import org.teavm.classlib.impl.tz.TimeZoneGenerator; import org.teavm.classlib.impl.unicode.AvailableLocalesMetadataGenerator; import org.teavm.classlib.impl.unicode.CLDRHelper; @@ -147,6 +148,15 @@ public class JCLPlugin implements TeaVMPlugin { installMetadata(host.getService(MetadataRegistration.class)); host.add(new DeclaringClassDependencyListener()); + applyTimeZoneDetection(host); + } + + private void applyTimeZoneDetection(TeaVMHost host) { + boolean autodetect = Boolean.parseBoolean( + host.getProperties().getProperty("java.util.TimeZone.autodetect", "false")); + if (!autodetect) { + host.add(new DateTimeZoneProviderPatch()); + } } private void installMetadata(MetadataRegistration reg) { 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 cdc367da4..730402459 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 @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; import java.util.PriorityQueue; import java.util.Set; -import org.teavm.backend.javascript.spi.GeneratedBy; import org.teavm.classlib.impl.Base46; import org.teavm.classlib.impl.CharFlow; import org.teavm.interop.Import; @@ -73,14 +72,7 @@ public final class DateTimeZoneProvider { return ids.toArray(new String[ids.size()]); } - @GeneratedBy(DateTimeZoneProviderGenerator.class) - private static native boolean timeZoneDetectionEnabled(); - public static DateTimeZone detectTimezone() { - if (!timeZoneDetectionEnabled()) { - return null; - } - List zones = new ArrayList<>(); long time = System.currentTimeMillis(); int offset = -getNativeOffset(System.currentTimeMillis()); 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 deleted file mode 100644 index 1138dfd37..000000000 --- a/classlib/src/main/java/org/teavm/classlib/impl/tz/DateTimeZoneProviderGenerator.java +++ /dev/null @@ -1,31 +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.classlib.impl.tz; - -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.MethodReference; - -public class DateTimeZoneProviderGenerator implements Generator { - @Override - 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 " + autodetect + ";"); - } -} diff --git a/classlib/src/main/java/org/teavm/classlib/impl/tz/DateTimeZoneProviderPatch.java b/classlib/src/main/java/org/teavm/classlib/impl/tz/DateTimeZoneProviderPatch.java new file mode 100644 index 000000000..03968a4a3 --- /dev/null +++ b/classlib/src/main/java/org/teavm/classlib/impl/tz/DateTimeZoneProviderPatch.java @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.classlib.impl.tz; + +import java.util.TimeZone; +import org.teavm.model.ClassHolder; +import org.teavm.model.ClassHolderTransformer; +import org.teavm.model.ClassHolderTransformerContext; +import org.teavm.model.MethodDescriptor; +import org.teavm.model.MethodHolder; +import org.teavm.model.emit.ProgramEmitter; + +public class DateTimeZoneProviderPatch implements ClassHolderTransformer { + @Override + public void transformClass(ClassHolder cls, ClassHolderTransformerContext context) { + if (cls.getName().equals(DateTimeZoneProvider.class.getName())) { + MethodHolder method = cls.getMethod(new MethodDescriptor("detectTimezone", DateTimeZone.class)); + if (method != null) { + method.setProgram(null); + ProgramEmitter pe = ProgramEmitter.create(method, context.getHierarchy()); + pe.constantNull(DateTimeZone.class).returnValue(); + } + } else if (cls.getName().equals(TimeZone.class.getName())) { + MethodHolder method = cls.getMethod(new MethodDescriptor("detectTimezone", TimeZone.class)); + if (method != null) { + method.setProgram(null); + ProgramEmitter pe = ProgramEmitter.create(method, context.getHierarchy()); + pe.constantNull(TimeZone.class).returnValue(); + } + } + } +} diff --git a/classlib/src/main/java/org/teavm/classlib/impl/tz/TimeZoneGenerator.java b/classlib/src/main/java/org/teavm/classlib/impl/tz/TimeZoneGenerator.java index 77c04ee80..4dca03ad1 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/tz/TimeZoneGenerator.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/tz/TimeZoneGenerator.java @@ -71,13 +71,13 @@ public class TimeZoneGenerator implements MetadataGenerator { public ResourceMap> generateMetadata( MetadataGeneratorContext context, MethodReference method) { ResourceMap> result = context.createResourceMap(); - ZoneInfoCompiler compiler = new ZoneInfoCompiler(); Collection zones; try (InputStream input = context.getClassLoader().getResourceAsStream("org/teavm/classlib/impl/tz/cache")) { if (input != null) { TimeZoneCache cache = new TimeZoneCache(); zones = cache.read(new BufferedInputStream(input)).values(); } else { + ZoneInfoCompiler compiler = new ZoneInfoCompiler(); compile(compiler, context.getClassLoader()); zones = compiler.compile().values(); } diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/TTimeZone.java b/classlib/src/main/java/org/teavm/classlib/java/util/TTimeZone.java index 5647b4b10..285c18e0f 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/TTimeZone.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/TTimeZone.java @@ -152,16 +152,19 @@ public abstract class TTimeZone implements Serializable, Cloneable { */ public static TTimeZone getDefault() { if (defaultTz == null) { - DateTimeZone innerTz = DateTimeZoneProvider.detectTimezone(); - if (innerTz != null) { - defaultTz = new TIANATimeZone(innerTz); - } else { - defaultTz = TTimeZone.getTimeZone("UTC"); + defaultTz = detectTimezone(); + if (defaultTz == null) { + defaultTz = TTimeZone.GMT; } } return (TTimeZone) defaultTz.clone(); } + private static TTimeZone detectTimezone() { + DateTimeZone innerTz = DateTimeZoneProvider.detectTimezone(); + return innerTz != null ? new TIANATimeZone(innerTz) : null; + } + /** * Gets the LONG name for this {@code TimeZone} for the default {@code Locale} in standard * time. If the name is not available, the result is in the format diff --git a/tools/cli/pom.xml b/tools/cli/pom.xml index 93a694ed3..10216b1d4 100644 --- a/tools/cli/pom.xml +++ b/tools/cli/pom.xml @@ -136,6 +136,7 @@ junit:junit com.fasterxml.jackson.core:jackson-annotations org.mozilla:rhino + joda-time:joda-time diff --git a/tools/idea/idea-artifacts/dep-pom.xml b/tools/idea/idea-artifacts/dep-pom.xml index 4a6477e75..cf6327263 100644 --- a/tools/idea/idea-artifacts/dep-pom.xml +++ b/tools/idea/idea-artifacts/dep-pom.xml @@ -119,6 +119,7 @@ com.jetbrains.intellij.idea:ideaIC:zip:* + joda-time:joda-time false