Goes on further with rewriting locale code with metadata providers

This commit is contained in:
konsoletyper 2014-06-11 17:10:58 +04:00
parent 5063091126
commit 7512817b3a
9 changed files with 129 additions and 90 deletions

View File

@ -47,7 +47,6 @@ public class JCLPlugin implements TeaVMPlugin {
host.registerService(CLDRReader.class, new CLDRReader(host.getProperties(), host.getClassLoader()));
Generator localeGen = new LocaleSettingsNativeGenerator(host.getClassLoader(), host.getProperties());
host.add(new MethodReference("java.util.Locale", "readCountriesFromCLDR", ValueType.VOID), localeGen);
host.add(new MethodReference("java.util.Calendar", "readWeeksFromCDLR", ValueType.VOID), localeGen);
host.add(new MethodReference(CLDRHelper.class.getName(), "readLikelySubtagsFromCLDR", ValueType.VOID),
localeGen);

View File

@ -61,4 +61,10 @@ public class CLDRHelper {
@MetadataProvider(LanguageMetadataGenerator.class)
public static native ResourceMap<ResourceMap<StringResource>> getLanguagesMap();
@MetadataProvider(CountryMetadataGenerator.class)
public static native ResourceMap<ResourceMap<StringResource>> getCountriesMap();
@MetadataProvider(DefaultLocaleMetadataGenerator.class)
public static native StringResource getDefaultLocale();
}

View File

@ -0,0 +1,29 @@
/*
* 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.classlib.impl.unicode;
import java.util.Map;
/**
*
* @author Alexey Andreev
*/
public class CountryMetadataGenerator extends LocaleMetadataGenerator {
@Override
protected Map<String, String> getNameMap(CLDRLocale locale) {
return locale.getTerritories();
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.classlib.impl.unicode;
import org.teavm.model.MethodReference;
import org.teavm.platform.metadata.MetadataGenerator;
import org.teavm.platform.metadata.MetadataGeneratorContext;
import org.teavm.platform.metadata.Resource;
import org.teavm.platform.metadata.StringResource;
/**
*
* @author Alexey Andreev
*/
public class DefaultLocaleMetadataGenerator implements MetadataGenerator {
@Override
public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) {
StringResource result = context.createResource(StringResource.class);
result.setValue(context.getProperties().getProperty("java.util.Locale.default", "en_EN"));
return result;
}
}

View File

@ -16,28 +16,14 @@
package org.teavm.classlib.impl.unicode;
import java.util.Map;
import org.teavm.model.MethodReference;
import org.teavm.platform.metadata.*;
/**
*
* @author Alexey Andreev
*/
public class LanguageMetadataGenerator implements MetadataGenerator {
public class LanguageMetadataGenerator extends LocaleMetadataGenerator {
@Override
public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) {
ResourceMap<ResourceMap<StringResource>> languages = context.createResourceMap();
CLDRReader reader = context.getService(CLDRReader.class);
for (Map.Entry<String, CLDRLocale> entry : reader.getKnownLocales().entrySet()) {
CLDRLocale locale = entry.getValue();
ResourceMap<StringResource> languageNames = context.createResourceMap();
languages.put(entry.getKey(), languageNames);
for (Map.Entry<String, String> language : locale.getLanguages().entrySet()) {
StringResource languageName = context.createResource(StringResource.class);
languageName.setValue(language.getValue());
languageNames.put(language.getKey(), languageName);
}
}
return languages;
protected Map<String, String> getNameMap(CLDRLocale locale) {
return locale.getLanguages();
}
}

View File

@ -0,0 +1,45 @@
/*
* 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.classlib.impl.unicode;
import java.util.Map;
import org.teavm.model.MethodReference;
import org.teavm.platform.metadata.*;
/**
*
* @author Alexey Andreev
*/
public abstract class LocaleMetadataGenerator implements MetadataGenerator {
@Override
public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) {
ResourceMap<ResourceMap<StringResource>> result = context.createResourceMap();
CLDRReader reader = context.getService(CLDRReader.class);
for (Map.Entry<String, CLDRLocale> entry : reader.getKnownLocales().entrySet()) {
CLDRLocale locale = entry.getValue();
ResourceMap<StringResource> names = context.createResourceMap();
result.put(entry.getKey(), names);
for (Map.Entry<String, String> nameEntry : getNameMap(locale).entrySet()) {
StringResource name = context.createResource(StringResource.class);
name.setValue(nameEntry.getValue());
names.put(nameEntry.getKey(), name);
}
}
return result;
}
protected abstract Map<String, String> getNameMap(CLDRLocale locale);
}

View File

@ -32,23 +32,6 @@ public class LocaleNativeGenerator implements Generator, DependencyPlugin {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
switch (methodRef.getName()) {
case "prepareCLDR":
writer.appendClass("java.util.Locale").append(".$CLDR = {};").softNewLine();
break;
case "getDisplayCountry":
writer.append("var result = ").appendClass("java.util.Locale").append(".$CLDR.territories[$rt_ustr(")
.append(context.getParameterName(1)).append(")];").softNewLine();
writer.append("result = result ? result[$rt_ustr(")
.append(context.getParameterName(2)).append(")] : undefined;").softNewLine();
writer.append("return result ? $rt_str(result) : null").softNewLine();
break;
case "getDisplayLanguage":
writer.append("var result = ").appendClass("java.util.Locale").append(".$CLDR.languages[$rt_ustr(")
.append(context.getParameterName(1)).append(")];").softNewLine();
writer.append("result = result ? result[$rt_ustr(")
.append(context.getParameterName(2)).append(")] : undefined;").softNewLine();
writer.append("return result ? $rt_str(result) : null;").softNewLine();
break;
case "getAvailableLocaleStrings":
generateAvailableLocales(writer);
break;
@ -69,7 +52,6 @@ public class LocaleNativeGenerator implements Generator, DependencyPlugin {
@Override
public void methodAchieved(DependencyAgent agent, MethodDependency method) {
switch (method.getMethod().getName()) {
case "getDefaultLocale":
case "getDisplayCountry":
case "getDisplayLanguage":
method.getResult().propagate("java.lang.String");

View File

@ -193,9 +193,6 @@ public class LocaleSettingsNativeGenerator implements Generator {
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
init();
switch (methodRef.getName()) {
case "readCountriesFromCLDR":
generateReadCountriesFromCLDR(writer);
break;
case "readWeeksFromCDLR":
generateReadWeeksFromCDLR(writer);
break;
@ -205,9 +202,6 @@ public class LocaleSettingsNativeGenerator implements Generator {
case "readAvailableLocales":
generateReadAvailableLocales(writer);
break;
case "getDefaultLocale":
generateGetDefaultLocale(writer);
break;
}
}
@ -232,33 +226,6 @@ public class LocaleSettingsNativeGenerator implements Generator {
writer.append("];").softNewLine();
}
private void generateReadCountriesFromCLDR(SourceWriter writer) throws IOException {
generateDefender(writer, "territories");
writer.appendClass("java.util.Locale").append(".$CLDR.territories = {").indent().softNewLine();
boolean firstLocale = true;
for (Map.Entry<String, LocaleInfo> entry : knownLocales.entrySet()) {
if (!firstLocale) {
writer.append(",").softNewLine();
}
firstLocale = false;
writer.append('"').append(Renderer.escapeString(entry.getKey())).append('"').ws().append(":").ws()
.append('{').indent().softNewLine();
boolean first = true;
for (Map.Entry<String, String> langEntry : entry.getValue().territories.entrySet()) {
if (!first) {
writer.append(',').softNewLine();
}
first = false;
writer.append('"').append(Renderer.escapeString(langEntry.getKey())).append('"').ws().append(':')
.ws().append('"').append(Renderer.escapeString(langEntry.getValue())).append('"');
}
writer.outdent().append('}');
}
writer.outdent().append("};").softNewLine();
}
private void generateReadWeeksFromCDLR(SourceWriter writer) throws IOException {
generateDefender(writer, "minDays");
writer.appendClass("java.util.Locale").append(".$CLDR.minDays = {").indent().softNewLine();
@ -301,11 +268,6 @@ public class LocaleSettingsNativeGenerator implements Generator {
writer.outdent().append("};").softNewLine();
}
private void generateGetDefaultLocale(SourceWriter writer) throws IOException {
String locale = properties.getProperty("java.util.Locale.default", "en_EN");
writer.append("return $rt_str(\"").append(Renderer.escapeString(locale)).append("\");").softNewLine();
}
static class LocaleInfo {
Map<String, String> languages = new LinkedHashMap<>();
Map<String, String> territories = new LinkedHashMap<>();

View File

@ -68,26 +68,15 @@ public final class TLocale implements TCloneable, TSerializable {
private static TLocale[] availableLocales;
static {
String localeName = getDefaultLocale();
String localeName = CLDRHelper.getDefaultLocale().getValue();
int countryIndex = localeName.indexOf('_');
defaultLocale = new TLocale(localeName.substring(0, countryIndex), localeName.substring(countryIndex) + 1, "");
prepareCLDR();
}
private transient String countryCode;
private transient String languageCode;
private transient String variantCode;
// Redefined by JCLPlugin
@PluggableDependency(LocaleNativeGenerator.class)
private static native String getDefaultLocale();
@GeneratedBy(LocaleNativeGenerator.class)
private static native void prepareCLDR();
// Redefined by JCLPlugin
private static native void readCountriesFromCLDR();
// Redefined by JCLPlugin
private static native void readAvailableLocales();
@ -172,7 +161,6 @@ public final class TLocale implements TCloneable, TSerializable {
}
public String getDisplayCountry(TLocale locale) {
readCountriesFromCLDR();
String result = getDisplayCountry(locale.getLanguage() + "-" + locale.getCountry(), countryCode);
if (result == null) {
result = getDisplayCountry(locale.getLanguage(), countryCode);
@ -180,9 +168,16 @@ public final class TLocale implements TCloneable, TSerializable {
return result != null ? result : countryCode;
}
@GeneratedBy(LocaleNativeGenerator.class)
@PluggableDependency(LocaleNativeGenerator.class)
private static native String getDisplayCountry(String localeName, String country);
private static String getDisplayCountry(String localeName, String country) {
if (!CLDRHelper.getCountriesMap().has(localeName)) {
return null;
}
ResourceMap<StringResource> countries = CLDRHelper.getCountriesMap().get(localeName);
if (!countries.has(country)) {
return null;
}
return countries.get(country).getValue();
}
public final String getDisplayLanguage() {
return getDisplayLanguage(getDefault());