/ runtime / IntlLocalePrototype.cpp
IntlLocalePrototype.cpp
  1  /*
  2   * Copyright (C) 2020 Sony Interactive Entertainment Inc.
  3   *
  4   * Redistribution and use in source and binary forms, with or without
  5   * modification, are permitted provided that the following conditions
  6   * are met:
  7   * 1. Redistributions of source code must retain the above copyright
  8   *    notice, this list of conditions and the following disclaimer.
  9   * 2. Redistributions in binary form must reproduce the above copyright
 10   *    notice, this list of conditions and the following disclaimer in the
 11   *    documentation and/or other materials provided with the distribution.
 12   *
 13   * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23   * THE POSSIBILITY OF SUCH DAMAGE.
 24   */
 25  
 26  #include "config.h"
 27  #include "IntlLocalePrototype.h"
 28  
 29  #include "IntlLocale.h"
 30  #include "JSCInlines.h"
 31  
 32  namespace JSC {
 33  
 34  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeFuncMaximize);
 35  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeFuncMinimize);
 36  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeFuncToString);
 37  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeGetterBaseName);
 38  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeGetterCalendar);
 39  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeGetterCaseFirst);
 40  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeGetterCollation);
 41  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeGetterHourCycle);
 42  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeGetterNumeric);
 43  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeGetterNumberingSystem);
 44  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeGetterLanguage);
 45  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeGetterScript);
 46  static JSC_DECLARE_HOST_FUNCTION(IntlLocalePrototypeGetterRegion);
 47  
 48  }
 49  
 50  #include "IntlLocalePrototype.lut.h"
 51  
 52  namespace JSC {
 53  
 54  const ClassInfo IntlLocalePrototype::s_info = { "Intl.Locale", &Base::s_info, &localePrototypeTable, nullptr, CREATE_METHOD_TABLE(IntlLocalePrototype) };
 55  
 56  /* Source for IntlLocalePrototype.lut.h
 57  @begin localePrototypeTable
 58    maximize         IntlLocalePrototypeFuncMaximize           DontEnum|Function 0
 59    minimize         IntlLocalePrototypeFuncMinimize           DontEnum|Function 0
 60    toString         IntlLocalePrototypeFuncToString           DontEnum|Function 0
 61    baseName         IntlLocalePrototypeGetterBaseName         DontEnum|Accessor
 62    calendar         IntlLocalePrototypeGetterCalendar         DontEnum|Accessor
 63    caseFirst        IntlLocalePrototypeGetterCaseFirst        DontEnum|Accessor
 64    collation        IntlLocalePrototypeGetterCollation        DontEnum|Accessor
 65    hourCycle        IntlLocalePrototypeGetterHourCycle        DontEnum|Accessor
 66    numeric          IntlLocalePrototypeGetterNumeric          DontEnum|Accessor
 67    numberingSystem  IntlLocalePrototypeGetterNumberingSystem  DontEnum|Accessor
 68    language         IntlLocalePrototypeGetterLanguage         DontEnum|Accessor
 69    script           IntlLocalePrototypeGetterScript           DontEnum|Accessor
 70    region           IntlLocalePrototypeGetterRegion           DontEnum|Accessor
 71  @end
 72  */
 73  
 74  IntlLocalePrototype* IntlLocalePrototype::create(VM& vm, Structure* structure)
 75  {
 76      auto* object = new (NotNull, allocateCell<IntlLocalePrototype>(vm.heap)) IntlLocalePrototype(vm, structure);
 77      object->finishCreation(vm);
 78      return object;
 79  }
 80  
 81  Structure* IntlLocalePrototype::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
 82  {
 83      return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
 84  }
 85  
 86  IntlLocalePrototype::IntlLocalePrototype(VM& vm, Structure* structure)
 87      : Base(vm, structure)
 88  {
 89  }
 90  
 91  void IntlLocalePrototype::finishCreation(VM& vm)
 92  {
 93      Base::finishCreation(vm);
 94      ASSERT(inherits(vm, info()));
 95      JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
 96  }
 97  
 98  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.maximize
 99  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeFuncMaximize, (JSGlobalObject* globalObject, CallFrame* callFrame))
100  {
101      VM& vm = globalObject->vm();
102      auto scope = DECLARE_THROW_SCOPE(vm);
103  
104      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
105      if (!locale)
106          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.maximize called on value that's not an object initialized as a Locale"_s);
107  
108      IntlLocale* newLocale = IntlLocale::create(vm, globalObject->localeStructure());
109      scope.release();
110      newLocale->initializeLocale(globalObject, locale->maximal(), jsUndefined());
111      return JSValue::encode(newLocale);
112  }
113  
114  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize
115  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeFuncMinimize, (JSGlobalObject* globalObject, CallFrame* callFrame))
116  {
117      VM& vm = globalObject->vm();
118      auto scope = DECLARE_THROW_SCOPE(vm);
119  
120      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
121      if (!locale)
122          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.minimize called on value that's not an object initialized as a Locale"_s);
123  
124      IntlLocale* newLocale = IntlLocale::create(vm, globalObject->localeStructure());
125      scope.release();
126      newLocale->initializeLocale(globalObject, locale->minimal(), jsUndefined());
127      return JSValue::encode(newLocale);
128  }
129  
130  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString
131  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeFuncToString, (JSGlobalObject* globalObject, CallFrame* callFrame))
132  {
133      VM& vm = globalObject->vm();
134      auto scope = DECLARE_THROW_SCOPE(vm);
135  
136      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
137      if (!locale)
138          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.toString called on value that's not an object initialized as a Locale"_s);
139  
140      const String& fullString = locale->toString();
141      RELEASE_AND_RETURN(scope, JSValue::encode(fullString.isEmpty() ? jsUndefined() : jsString(vm, fullString)));
142  }
143  
144  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.baseName
145  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeGetterBaseName, (JSGlobalObject* globalObject, CallFrame* callFrame))
146  {
147      VM& vm = globalObject->vm();
148      auto scope = DECLARE_THROW_SCOPE(vm);
149  
150      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
151      if (!locale)
152          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.baseName called on value that's not an object initialized as a Locale"_s);
153  
154      const String& baseName = locale->baseName();
155      RELEASE_AND_RETURN(scope, JSValue::encode(baseName.isEmpty() ? jsUndefined() : jsString(vm, baseName)));
156  }
157  
158  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.calendar
159  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeGetterCalendar, (JSGlobalObject* globalObject, CallFrame* callFrame))
160  {
161      VM& vm = globalObject->vm();
162      auto scope = DECLARE_THROW_SCOPE(vm);
163  
164      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
165      if (!locale)
166          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.calendar called on value that's not an object initialized as a Locale"_s);
167  
168      const String& calendar = locale->calendar();
169      RELEASE_AND_RETURN(scope, JSValue::encode(calendar.isNull() ? jsUndefined() : jsString(vm, calendar)));
170  }
171  
172  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.caseFirst
173  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeGetterCaseFirst, (JSGlobalObject* globalObject, CallFrame* callFrame))
174  {
175      VM& vm = globalObject->vm();
176      auto scope = DECLARE_THROW_SCOPE(vm);
177  
178      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
179      if (!locale)
180          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.caseFirst called on value that's not an object initialized as a Locale"_s);
181  
182      const String& caseFirst = locale->caseFirst();
183      RELEASE_AND_RETURN(scope, JSValue::encode(caseFirst.isNull() ? jsUndefined() : jsString(vm, caseFirst)));
184  }
185  
186  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.collation
187  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeGetterCollation, (JSGlobalObject* globalObject, CallFrame* callFrame))
188  {
189      VM& vm = globalObject->vm();
190      auto scope = DECLARE_THROW_SCOPE(vm);
191  
192      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
193      if (!locale)
194          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.collation called on value that's not an object initialized as a Locale"_s);
195  
196      const String& collation = locale->collation();
197      RELEASE_AND_RETURN(scope, JSValue::encode(collation.isNull() ? jsUndefined() : jsString(vm, collation)));
198  }
199  
200  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.hourCycle
201  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeGetterHourCycle, (JSGlobalObject* globalObject, CallFrame* callFrame))
202  {
203      VM& vm = globalObject->vm();
204      auto scope = DECLARE_THROW_SCOPE(vm);
205  
206      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
207      if (!locale)
208          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.hourCycle called on value that's not an object initialized as a Locale"_s);
209  
210      const String& hourCycle = locale->hourCycle();
211      RELEASE_AND_RETURN(scope, JSValue::encode(hourCycle.isNull() ? jsUndefined() : jsString(vm, hourCycle)));
212  }
213  
214  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numeric
215  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeGetterNumeric, (JSGlobalObject* globalObject, CallFrame* callFrame))
216  {
217      VM& vm = globalObject->vm();
218      auto scope = DECLARE_THROW_SCOPE(vm);
219  
220      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
221      if (!locale)
222          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.numeric called on value that's not an object initialized as a Locale"_s);
223  
224      RELEASE_AND_RETURN(scope, JSValue::encode(jsBoolean(locale->numeric() == TriState::True)));
225  }
226  
227  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numberingSystem
228  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeGetterNumberingSystem, (JSGlobalObject* globalObject, CallFrame* callFrame))
229  {
230      VM& vm = globalObject->vm();
231      auto scope = DECLARE_THROW_SCOPE(vm);
232  
233      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
234      if (!locale)
235          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.numberingSystem called on value that's not an object initialized as a Locale"_s);
236  
237      const String& numberingSystem = locale->numberingSystem();
238      RELEASE_AND_RETURN(scope, JSValue::encode(numberingSystem.isNull() ? jsUndefined() : jsString(vm, numberingSystem)));
239  }
240  
241  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.language
242  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeGetterLanguage, (JSGlobalObject* globalObject, CallFrame* callFrame))
243  {
244      VM& vm = globalObject->vm();
245      auto scope = DECLARE_THROW_SCOPE(vm);
246  
247      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
248      if (!locale)
249          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.language called on value that's not an object initialized as a Locale"_s);
250  
251      const String& language = locale->language();
252      RELEASE_AND_RETURN(scope, JSValue::encode(language.isEmpty() ? jsUndefined() : jsString(vm, language)));
253  }
254  
255  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.script
256  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeGetterScript, (JSGlobalObject* globalObject, CallFrame* callFrame))
257  {
258      VM& vm = globalObject->vm();
259      auto scope = DECLARE_THROW_SCOPE(vm);
260  
261      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
262      if (!locale)
263          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.script called on value that's not an object initialized as a Locale"_s);
264  
265      const String& script = locale->script();
266      RELEASE_AND_RETURN(scope, JSValue::encode(script.isEmpty() ? jsUndefined() : jsString(vm, script)));
267  }
268  
269  // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.region
270  JSC_DEFINE_HOST_FUNCTION(IntlLocalePrototypeGetterRegion, (JSGlobalObject* globalObject, CallFrame* callFrame))
271  {
272      VM& vm = globalObject->vm();
273      auto scope = DECLARE_THROW_SCOPE(vm);
274  
275      auto* locale = jsDynamicCast<IntlLocale*>(vm, callFrame->thisValue());
276      if (!locale)
277          return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.region called on value that's not an object initialized as a Locale"_s);
278  
279      const String& region = locale->region();
280      RELEASE_AND_RETURN(scope, JSValue::encode(region.isEmpty() ? jsUndefined() : jsString(vm, region)));
281  }
282  
283  } // namespace JSC