Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // Mocks of classes and interfaces that Leg cannot read directly. | 5 // Mocks of classes and interfaces that Leg cannot read directly. |
| 6 | 6 |
| 7 // TODO(ahe): Remove this file. | 7 // TODO(ahe): Remove this file. |
| 8 | 8 |
| 9 class JSSyntaxRegExp implements RegExp { | 9 class JSSyntaxRegExp implements RegExp { |
| 10 JSSyntaxRegExp(String pattern, | 10 JSSyntaxRegExp(String pattern, |
| 11 [bool multiLine = false, | 11 [bool multiLine = false, |
| 12 bool ignoreCase = false]) { | 12 bool ignoreCase = false]) { |
| 13 throw 'JSSyntaxRegExp is not implemented'; | 13 throw 'JSSyntaxRegExp is not implemented'; |
| 14 } | 14 } |
| 15 } | 15 } |
| 16 | 16 |
| 17 class StringBufferImpl { | 17 class StringBufferImpl { |
| 18 StringBufferImpl() { | 18 StringBufferImpl() { |
| 19 throw 'StringBufferImpl is not implemented'; | 19 throw 'StringBufferImpl is not implemented'; |
| 20 } | 20 } |
| 21 } | 21 } |
| 22 | 22 |
| 23 class DateImplementation {} | 23 class ReceivePortFactory { |
| 24 class ReceivePortFactory {} | 24 factory ReceivePort() { |
| 25 throw 'factory ReceivePort is not implemented'; | |
| 26 } | |
| 27 | |
| 28 factory ReceivePort.singleShot() { | |
| 29 throw 'factory ReceivePort.singleShot is not implemented'; | |
| 30 } | |
| 31 } | |
| 25 | 32 |
| 26 class StringBase { | 33 class StringBase { |
| 27 static String createFromCharCodes(List<int> charCodes) { | 34 static String createFromCharCodes(List<int> charCodes) { |
| 28 throw "StringBase.createFromCharCodes is not implemented"; | 35 throw "StringBase.createFromCharCodes is not implemented"; |
| 29 } | 36 } |
| 30 | 37 |
| 31 static String join(List<String> strings, String separator) { | 38 static String join(List<String> strings, String separator) { |
| 32 throw "StringBase.join is not implemented"; | 39 throw "StringBase.join is not implemented"; |
| 33 } | 40 } |
| 34 | 41 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 } | 94 } |
| 88 | 95 |
| 89 static num pow(num value, num exponent) { | 96 static num pow(num value, num exponent) { |
| 90 throw 'MathNatives.pow is not implemented'; | 97 throw 'MathNatives.pow is not implemented'; |
| 91 } | 98 } |
| 92 | 99 |
| 93 static double random() { | 100 static double random() { |
| 94 throw 'MathNatives.random is not implemented'; | 101 throw 'MathNatives.random is not implemented'; |
| 95 } | 102 } |
| 96 } | 103 } |
| 104 | |
| 105 class TimeZoneImplementation implements TimeZone { | |
|
ngeoffray
2012/02/17 10:03:50
Why do you need to copy this over?
ahe
2012/02/17 16:26:46
I need the constructors.
| |
| 106 const TimeZoneImplementation.utc() : isUtc = true; | |
| 107 TimeZoneImplementation.local() : isUtc = false; | |
| 108 | |
| 109 bool operator ==(Object other) { | |
| 110 if (!(other is TimeZoneImplementation)) return false; | |
| 111 return isUtc == other.isUtc; | |
| 112 } | |
| 113 | |
| 114 final bool isUtc; | |
| 115 } | |
| 116 | |
| 117 class DateImplementation implements Date { | |
| 118 factory DateImplementation(int years, | |
| 119 int month, | |
| 120 int day, | |
| 121 int hours, | |
| 122 int minutes, | |
| 123 int seconds, | |
| 124 int milliseconds) { | |
| 125 return new DateImplementation.withTimeZone( | |
| 126 years, month, day, | |
| 127 hours, minutes, seconds, milliseconds, | |
| 128 new TimeZoneImplementation.local()); | |
| 129 } | |
| 130 | |
| 131 DateImplementation.withTimeZone(int years, | |
| 132 int month, | |
| 133 int day, | |
| 134 int hours, | |
| 135 int minutes, | |
| 136 int seconds, | |
| 137 int milliseconds, | |
| 138 TimeZoneImplementation timeZone) | |
| 139 : timeZone = timeZone, | |
| 140 value = brokenDownDateToMillisecondsSinceEpoch_( | |
| 141 years, month, day, hours, minutes, seconds, milliseconds, | |
| 142 timeZone.isUtc); | |
| 143 | |
| 144 DateImplementation.now() | |
| 145 : timeZone = new TimeZone.local(), | |
| 146 value = Primitives.getCurrentMs(); | |
| 147 | |
| 148 factory DateImplementation.fromString(String formattedString) { | |
| 149 int substringToNumber(String str, int from, int to) { | |
| 150 int result = 0; | |
| 151 for (int i = from; i < to; i++) { | |
| 152 result = result * 10 + str.charCodeAt(i) - "0".charCodeAt(0); | |
| 153 } | |
| 154 return result; | |
| 155 } | |
| 156 | |
| 157 // TODO(floitsch): improve DateImplementation parsing. | |
| 158 // Parse ISO 8601: "2011-05-14 00:37:18.231Z". | |
| 159 int yearMonthSeparator = formattedString.indexOf("-", 0); | |
| 160 if (yearMonthSeparator < 0) throw "UNIMPLEMENTED"; | |
| 161 int monthDaySeparator = | |
| 162 formattedString.indexOf("-", yearMonthSeparator + 1); | |
| 163 if (monthDaySeparator < 0) throw "UNIMPLEMENTED"; | |
| 164 int dateTimeSeparator = formattedString.indexOf(" ", monthDaySeparator + 1); | |
| 165 if (dateTimeSeparator < 0) throw "UNIMPLEMENTED"; | |
| 166 int hoursMinutesSeparator = | |
| 167 formattedString.indexOf(":", dateTimeSeparator + 1); | |
| 168 if (hoursMinutesSeparator < 0) throw "UNIMPLEMENTED"; | |
| 169 int minutesSecondsSeparator = | |
| 170 formattedString.indexOf(":", hoursMinutesSeparator + 1); | |
| 171 if (minutesSecondsSeparator < 0) throw "UNIMPLEMENTED"; | |
| 172 int secondsMillisecondsSeparator = | |
| 173 formattedString.indexOf(".", minutesSecondsSeparator + 1); | |
| 174 bool isUtc = formattedString.endsWith("Z"); | |
| 175 int end = formattedString.length - (isUtc ? 1 : 0); | |
| 176 if (secondsMillisecondsSeparator < 0) secondsMillisecondsSeparator = end; | |
| 177 | |
| 178 int year = substringToNumber(formattedString, 0, yearMonthSeparator); | |
| 179 int month = substringToNumber(formattedString, | |
| 180 yearMonthSeparator + 1, | |
| 181 monthDaySeparator); | |
| 182 int day = substringToNumber(formattedString, | |
| 183 monthDaySeparator + 1, | |
| 184 dateTimeSeparator); | |
| 185 int hours = substringToNumber(formattedString, | |
| 186 dateTimeSeparator + 1, | |
| 187 hoursMinutesSeparator); | |
| 188 int minutes = substringToNumber(formattedString, | |
| 189 hoursMinutesSeparator + 1, | |
| 190 minutesSecondsSeparator); | |
| 191 int seconds = substringToNumber(formattedString, | |
| 192 minutesSecondsSeparator + 1, | |
| 193 secondsMillisecondsSeparator); | |
| 194 int milliseconds = substringToNumber(formattedString, | |
| 195 secondsMillisecondsSeparator + 1, | |
| 196 end); | |
| 197 TimeZone timeZone = (isUtc ? const TimeZone.utc() : new TimeZone.local()); | |
| 198 return new DateImplementation.withTimeZone( | |
| 199 year, month, day, hours, minutes, seconds, milliseconds, timeZone); | |
| 200 } | |
| 201 | |
| 202 const DateImplementation.fromEpoch(int this.value, | |
| 203 TimeZone this.timeZone); | |
| 204 | |
| 205 bool operator ==(Object other) { | |
| 206 if (!(other is DateImplementation)) return false; | |
| 207 return value == other.value && timeZone == other.timeZone; | |
| 208 } | |
| 209 | |
| 210 int compareTo(Date other) { | |
| 211 return value.compareTo(other.value); | |
| 212 } | |
| 213 | |
| 214 Date changeTimeZone(TimeZone targetTimeZone) { | |
| 215 if (targetTimeZone === null) { | |
| 216 targetTimeZone = new TimeZoneImplementation.local(); | |
| 217 } | |
| 218 return new Date.fromEpoch(value, targetTimeZone); | |
| 219 } | |
| 220 | |
| 221 int get year() { | |
| 222 int secondsSinceEpoch = secondsSinceEpoch_; | |
| 223 // According to V8 some library calls have troubles with negative values. | |
| 224 // Therefore clamp to 0 - year 2035 (which is less than the size of 32bit). | |
| 225 if (secondsSinceEpoch >= 0 && secondsSinceEpoch < SECONDS_YEAR_2035_) { | |
| 226 return Primitives.getYear(secondsSinceEpoch, timeZone.isUtc); | |
| 227 } | |
| 228 | |
| 229 // Approximate the result. We don't take timeZone into account. | |
| 230 int approximateYear = yearsFromSecondsSinceEpoch_(secondsSinceEpoch); | |
| 231 int equivalentYear = equivalentYear_(approximateYear); | |
| 232 int y = Primitives.getYear(equivalentSeconds_(secondsSinceEpoch_), | |
| 233 timeZone.isUtc); | |
| 234 return approximateYear + (y - equivalentYear); | |
| 235 } | |
| 236 | |
| 237 int get month() => Primitives.getMonth(equivalentSeconds_(secondsSinceEpoch_), | |
| 238 timeZone.isUtc); | |
| 239 | |
| 240 int get day() => Primitives.getDay(equivalentSeconds_(secondsSinceEpoch_), | |
| 241 timeZone.isUtc); | |
| 242 | |
| 243 int get hours() => Primitives.getHours(equivalentSeconds_(secondsSinceEpoch_), | |
| 244 timeZone.isUtc); | |
| 245 | |
| 246 int get minutes() => | |
| 247 Primitives.getMinutes(equivalentSeconds_(secondsSinceEpoch_), | |
| 248 timeZone.isUtc); | |
| 249 | |
| 250 int get seconds() => | |
| 251 Primitives.getSeconds(equivalentSeconds_(secondsSinceEpoch_), | |
| 252 timeZone.isUtc); | |
| 253 | |
| 254 int get milliseconds() { | |
| 255 return value % Duration.MILLISECONDS_PER_SECOND; | |
| 256 } | |
| 257 | |
| 258 int get secondsSinceEpoch_() { | |
| 259 // Always round down. | |
| 260 if (value < 0) { | |
| 261 return (value + 1) ~/ Duration.MILLISECONDS_PER_SECOND - 1; | |
| 262 } else { | |
| 263 return value ~/ Duration.MILLISECONDS_PER_SECOND; | |
| 264 } | |
| 265 } | |
| 266 | |
| 267 int get weekday() { | |
| 268 final Date unixTimeStart = | |
| 269 new Date.withTimeZone(1970, 1, 1, 0, 0, 0, 0, timeZone); | |
| 270 int msSince1970 = this.difference(unixTimeStart).inMilliseconds; | |
| 271 // Adjust the milliseconds to avoid problems with summer-time. | |
| 272 if (hours < 2) { | |
| 273 msSince1970 += 2 * Duration.MILLISECONDS_PER_HOUR; | |
| 274 } | |
| 275 // Compute the floor of msSince1970 / Duration.MS_PER_DAY. | |
| 276 int daysSince1970; | |
| 277 if (msSince1970 >= 0) { | |
| 278 daysSince1970 = msSince1970 ~/ Duration.MILLISECONDS_PER_DAY; | |
| 279 } else { | |
| 280 daysSince1970 = (msSince1970 - Duration.MILLISECONDS_PER_DAY + 1) ~/ | |
| 281 Duration.MILLISECONDS_PER_DAY; | |
| 282 } | |
| 283 // 1970-1-1 was a Thursday. | |
| 284 return ((daysSince1970 + Date.THU) % Date.DAYS_IN_WEEK); | |
| 285 } | |
| 286 | |
| 287 bool isLocalTime() { | |
| 288 return !timeZone.isUtc; | |
| 289 } | |
| 290 | |
| 291 bool isUtc() { | |
| 292 return timeZone.isUtc; | |
| 293 } | |
| 294 | |
| 295 String toString() { | |
| 296 String threeDigits(int n) { | |
| 297 if (n >= 100) return "${n}"; | |
| 298 if (n > 10) return "0${n}"; | |
| 299 return "00${n}"; | |
| 300 } | |
| 301 String twoDigits(int n) { | |
| 302 if (n >= 10) return "${n}"; | |
| 303 return "0${n}"; | |
| 304 } | |
| 305 | |
| 306 String m = twoDigits(month); | |
| 307 String d = twoDigits(day); | |
| 308 String h = twoDigits(hours); | |
| 309 String min = twoDigits(minutes); | |
| 310 String sec = twoDigits(seconds); | |
| 311 String ms = threeDigits(milliseconds); | |
| 312 if (timeZone.isUtc) { | |
| 313 return "$year-$m-$d $h:$min:$sec.${ms}Z"; | |
| 314 } else { | |
| 315 return "$year-$m-$d $h:$min:$sec.$ms"; | |
| 316 } | |
| 317 } | |
| 318 | |
| 319 // Adds the [duration] to this Date instance. | |
| 320 Date add(Duration duration) { | |
| 321 return new DateImplementation.fromEpoch(value + duration.inMilliseconds, | |
| 322 timeZone); | |
| 323 } | |
| 324 | |
| 325 // Subtracts the [duration] from this Date instance. | |
| 326 Date subtract(Duration duration) { | |
| 327 return new DateImplementation.fromEpoch(value - duration.inMilliseconds, | |
| 328 timeZone); | |
| 329 } | |
| 330 | |
| 331 // Returns a [Duration] with the difference of [this] and [other]. | |
| 332 Duration difference(Date other) { | |
| 333 return new DurationImplementation(milliseconds: value - other.value); | |
| 334 } | |
| 335 | |
| 336 final int value; | |
| 337 final TimeZoneImplementation timeZone; | |
| 338 | |
| 339 static final int SECONDS_YEAR_2035_ = 2051222400; | |
| 340 | |
| 341 // Returns the UTC year for the corresponding [secondsSinceEpoch]. | |
| 342 // It is relatively fast for values in the range 0 to year 2098. | |
| 343 // Code is adapted from V8. | |
| 344 static int yearsFromSecondsSinceEpoch_(int secondsSinceEpoch) { | |
| 345 final int DAYS_IN_4_YEARS = 4 * 365 + 1; | |
| 346 final int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1; | |
| 347 final int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1; | |
| 348 final int DAYS_1970_TO_2000 = 30 * 365 + 7; | |
| 349 final int DAYS_OFFSET = 1000 * DAYS_IN_400_YEARS + 5 * DAYS_IN_400_YEARS - | |
| 350 DAYS_1970_TO_2000; | |
| 351 final int YEARS_OFFSET = 400000; | |
| 352 final int DAYS_YEAR_2098 = DAYS_IN_100_YEARS + 6 * DAYS_IN_4_YEARS; | |
| 353 | |
| 354 int days = secondsSinceEpoch ~/ Duration.SECONDS_PER_DAY; | |
| 355 if (days > 0 && days < DAYS_YEAR_2098) { | |
| 356 // According to V8 this fast case works for dates from 1970 to 2099. | |
| 357 return 1970 + (4 * days + 2) ~/ DAYS_IN_4_YEARS; | |
| 358 } else { | |
| 359 days += DAYS_OFFSET; | |
| 360 int result = 400 * (days ~/ DAYS_IN_400_YEARS) - YEARS_OFFSET; | |
| 361 days = days.remainder(DAYS_IN_400_YEARS); | |
| 362 days--; | |
| 363 int yd1 = days ~/ DAYS_IN_100_YEARS; | |
| 364 days = days.remainder(DAYS_IN_100_YEARS); | |
| 365 result += 100 * yd1; | |
| 366 days++; | |
| 367 int yd2 = days ~/ DAYS_IN_4_YEARS; | |
| 368 days = days.remainder(DAYS_IN_4_YEARS); | |
| 369 result += 4 * yd2; | |
| 370 days--; | |
| 371 int yd3 = days ~/ 365; | |
| 372 days = days.remainder(365); | |
| 373 result += yd3; | |
| 374 return result; | |
| 375 } | |
| 376 } | |
| 377 | |
| 378 // Given [secondsSinceEpoch] returns seconds such that they are at the same | |
| 379 // time in an equivalent year (see [equivalentYear_]). | |
| 380 // Leap seconds are ignored. | |
| 381 static int equivalentSeconds_(int secondsSinceEpoch) { | |
| 382 if (secondsSinceEpoch >= 0 && secondsSinceEpoch < SECONDS_YEAR_2035_) { | |
| 383 return secondsSinceEpoch; | |
| 384 } | |
| 385 int year = yearsFromSecondsSinceEpoch_(secondsSinceEpoch); | |
| 386 int days = dayFromYear_(year); | |
| 387 int equivalentYear = equivalentYear_(year); | |
| 388 int equivalentDays = dayFromYear_(equivalentYear); | |
| 389 int diffDays = equivalentDays - days; | |
| 390 return secondsSinceEpoch + diffDays * Duration.SECONDS_PER_DAY; | |
| 391 } | |
| 392 | |
| 393 // Returns the days since 1970 for the start of the given [year]. | |
| 394 // [year] may be before epoch. | |
| 395 static int dayFromYear_(int year) { | |
| 396 int flooredDivision(int a, int b) { | |
| 397 return (a - (a < 0 ? b - 1 : 0)) ~/ b; | |
| 398 } | |
| 399 | |
| 400 return 365 * (year - 1970) | |
| 401 + flooredDivision(year - 1969, 4) | |
| 402 - flooredDivision(year - 1901, 100) | |
| 403 + flooredDivision(year - 1601, 400); | |
| 404 } | |
| 405 | |
| 406 // Returns a year in the range 2008-2035 matching | |
| 407 // - leap year, and | |
| 408 // - week day of first day. | |
| 409 // Leap seconds are ignored. | |
| 410 // Adapted from V8's date implementation. See ECMA 262 - 15.9.1.9. | |
| 411 static equivalentYear_(int year) { | |
| 412 // Returns 1 if in leap year. 0 otherwise. | |
| 413 bool inLeapYear(year) { | |
| 414 return (year.remainder(4) == 0) && | |
| 415 ((year.remainder(100) != 0) || (year.remainder(400) == 0)); | |
| 416 } | |
| 417 | |
| 418 // Returns the week day (in range 0 - 6). | |
| 419 int weekDay(year) { | |
| 420 // 1/1/1970 was a Thursday. | |
| 421 return (dayFromYear_(year) + 4) % 7; | |
| 422 } | |
| 423 // 1/1/1956 was a Sunday (i.e. weekday 0). 1956 was a leap-year. | |
| 424 // 1/1/1967 was a Sunday (i.e. weekday 0). | |
| 425 // Without leap years a subsequent year has a week day + 1 (for example | |
| 426 // 1/1/1968 was a Monday). With leap-years it jumps over one week day | |
| 427 // (e.g. 1/1/1957 was a Tuesday). | |
| 428 // After 12 years the weekdays have advanced by 12 days + 3 leap days = | |
| 429 // 15 days. 15 % 7 = 1. So after 12 years the week day has always | |
| 430 // (now independently of leap-years) advanced by one. | |
| 431 // weekDay * 12 gives thus a year starting with the wanted weekDay. | |
| 432 int recentYear = (inLeapYear(year) ? 1956 : 1967) + (weekDay(year) * 12); | |
| 433 // Close to the year 2008 the calendar cycles every 4 * 7 years (4 for the | |
| 434 // leap years, 7 for the weekdays). | |
| 435 // Find the year in the range 2008..2037 that is equivalent mod 28. | |
| 436 return 2008 + (recentYear - 2008) % 28; | |
| 437 } | |
| 438 | |
| 439 static brokenDownDateToMillisecondsSinceEpoch_( | |
| 440 int years, int month, int day, | |
| 441 int hours, int minutes, int seconds, int milliseconds, | |
| 442 bool isUtc) { | |
| 443 if ((month < 1) || (month > 12)) { | |
| 444 throw new IllegalArgumentException(); | |
| 445 } | |
| 446 if ((day < 1) || (day > 31)) { | |
| 447 throw new IllegalArgumentException(); | |
| 448 } | |
| 449 // Leap seconds can lead to hours == 24. | |
| 450 if ((hours < 0) || (hours > 24)) { | |
| 451 throw new IllegalArgumentException(); | |
| 452 } | |
| 453 if ((hours == 24) && ((minutes != 0) || (seconds != 0))) { | |
| 454 throw new IllegalArgumentException(); | |
| 455 } | |
| 456 if ((minutes < 0) || (minutes > 59)) { | |
| 457 throw new IllegalArgumentException(); | |
| 458 } | |
| 459 if ((seconds < 0) || (seconds > 59)) { | |
| 460 throw new IllegalArgumentException(); | |
| 461 } | |
| 462 if ((milliseconds < 0) || (milliseconds > 999)) { | |
| 463 throw new IllegalArgumentException(); | |
| 464 } | |
| 465 int equivalentYear; | |
| 466 int offsetInSeconds; | |
| 467 // According to V8 some library calls have troubles with negative values. | |
| 468 // Therefore clamp to 1970 - year 2035 (which is less than the size of | |
| 469 // 32bit). | |
| 470 // We exclude the year 1970 when the time is not UTC, since the epoch | |
| 471 // value could then be negative. | |
| 472 if (years < (isUtc ? 1970 : 1971) || years > 2035) { | |
| 473 equivalentYear = equivalentYear_(years); | |
| 474 int offsetInDays = (dayFromYear_(years) - dayFromYear_(equivalentYear)); | |
| 475 // Leap seconds are ignored. | |
| 476 offsetInSeconds = offsetInDays * Duration.SECONDS_PER_DAY; | |
| 477 } else { | |
| 478 equivalentYear = years; | |
| 479 offsetInSeconds = 0; | |
| 480 } | |
| 481 int secondsSinceEpoch = Primitives.brokenDownDateToSecondsSinceEpoch( | |
| 482 equivalentYear, month, day, hours, minutes, seconds, isUtc); | |
| 483 int adjustedSeconds = secondsSinceEpoch + offsetInSeconds; | |
| 484 return adjustedSeconds * Duration.MILLISECONDS_PER_SECOND + milliseconds; | |
| 485 } | |
| 486 } | |
| OLD | NEW |