Minor improvements to time zone support

This commit is contained in:
Alexey Andreev 2020-04-30 15:49:37 +03:00
parent a9e7e51c51
commit 9f823ee450
8 changed files with 66 additions and 45 deletions

View File

@ -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) {

View File

@ -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<Score> zones = new ArrayList<>();
long time = System.currentTimeMillis();
int offset = -getNativeOffset(System.currentTimeMillis());

View File

@ -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 + ";");
}
}

View File

@ -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();
}
}
}
}

View File

@ -71,13 +71,13 @@ public class TimeZoneGenerator implements MetadataGenerator {
public ResourceMap<ResourceMap<TimeZoneResource>> generateMetadata(
MetadataGeneratorContext context, MethodReference method) {
ResourceMap<ResourceMap<TimeZoneResource>> result = context.createResourceMap();
ZoneInfoCompiler compiler = new ZoneInfoCompiler();
Collection<StorableDateTimeZone> 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();
}

View File

@ -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

View File

@ -136,6 +136,7 @@
<exclude>junit:junit</exclude>
<exclude>com.fasterxml.jackson.core:jackson-annotations</exclude>
<exclude>org.mozilla:rhino</exclude>
<exclude>joda-time:joda-time</exclude>
</excludes>
</artifactSet>
<transformers>

View File

@ -119,6 +119,7 @@
<atrifactSet>
<excludes>
<exclude>com.jetbrains.intellij.idea:ideaIC:zip:*</exclude>
<exclude>joda-time:joda-time</exclude>
</excludes>
</atrifactSet>
<createDependencyReducedPom>false</createDependencyReducedPom>