mirror of
https://github.com/enso-org/enso.git
synced 2024-12-22 17:41:53 +03:00
Duration type is a builtin type (#3759)
- Reimplement the `Duration` type to a built-in type. - `Duration` is an interop type. - Allow Enso method dispatch on `Duration` interop coming from different languages. # Important Notes - The older `Duration` type should now be split into new `Duration` builtin type and a `Period` type. - This PR does not implement `Period` type, so all the `Period`-related functionality is currently not working, e.g., `Date - Period`. - This PR removes `Integer.milliseconds`, `Integer.seconds`, ..., `Integer.years` extension methods.
This commit is contained in:
parent
ce6267f098
commit
e9260227c4
@ -209,6 +209,7 @@
|
||||
- [Added `Filter_Condition` to `Vector`, `Range` and `List`.][3770]
|
||||
- [Extended `Filter_Condition` with `Is_Empty`, `Not_Empty`, `Like` and
|
||||
`Not_Like`.][3775]
|
||||
- [Reimplemented `Duration` as a built-in type.][3759]
|
||||
- [Implemented `Table.replace_text` for in-memory table.][3793]
|
||||
|
||||
[debug-shortcuts]:
|
||||
@ -336,6 +337,7 @@
|
||||
[3750]: https://github.com/enso-org/enso/pull/3750
|
||||
[3770]: https://github.com/enso-org/enso/pull/3770
|
||||
[3775]: https://github.com/enso-org/enso/pull/3775
|
||||
[3759]: https://github.com/enso-org/enso/pull/3759
|
||||
[3793]: https://github.com/enso-org/enso/pull/3793
|
||||
|
||||
#### Enso Compiler
|
||||
|
@ -1891,8 +1891,7 @@ lazy val `std-table` = project
|
||||
.copyDependencies(
|
||||
`table-polyglot-root`,
|
||||
Some("std-table.jar"),
|
||||
ignoreScalaLibrary = true,
|
||||
unpackedDeps = Set("xmlbeans")
|
||||
ignoreScalaLibrary = true
|
||||
)
|
||||
.value
|
||||
result
|
||||
|
@ -4,7 +4,7 @@ import Standard.Base.Data.Time.Duration
|
||||
import Standard.Base.Data.Time.Date_Period
|
||||
|
||||
import Standard.Base.Polyglot
|
||||
from Standard.Base.Error.Common import Time_Error_Data
|
||||
from Standard.Base.Error.Common import Time_Error_Data, unimplemented
|
||||
|
||||
polyglot java import org.enso.base.Time_Utils
|
||||
polyglot java import java.time.temporal.ChronoField
|
||||
@ -308,9 +308,8 @@ type Date
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_add = Date.new 2020 + 6.months
|
||||
+ : Duration -> Date
|
||||
+ self amount = if amount.is_time then Error.throw (Time_Error_Data "Date does not support time intervals") else
|
||||
(Time_Utils.date_adjust self Time_Utils.AdjustOp.PLUS amount.internal_period) . internal_local_date
|
||||
+ : Date_Period -> Date
|
||||
+ self _ = unimplemented "Date.+"
|
||||
|
||||
## Shift the date by the specified amount of business days.
|
||||
|
||||
@ -433,9 +432,8 @@ type Date
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_subtract = Date.new 2020 - 7.days
|
||||
- : Duration -> Date
|
||||
- self amount = if amount.is_time then Error.throw (Time_Error_Data "Date does not support time intervals") else
|
||||
(Time_Utils.date_adjust self Time_Utils.AdjustOp.MINUS amount.internal_period) . internal_local_date
|
||||
- : Date_Period -> Date
|
||||
- self _ = unimplemented "Date.-"
|
||||
|
||||
|
||||
## A Date to Json conversion.
|
||||
|
@ -8,6 +8,7 @@ from Standard.Base.Error.Common import Time_Error
|
||||
polyglot java import java.time.format.DateTimeFormatter
|
||||
polyglot java import java.time.temporal.ChronoField
|
||||
polyglot java import java.time.temporal.IsoFields
|
||||
polyglot java import java.lang.ArithmeticException
|
||||
|
||||
polyglot java import org.enso.base.Time_Utils
|
||||
|
||||
@ -387,10 +388,10 @@ type Date_Time
|
||||
from Standard.Base import Date_Time
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_plus = Date_Time.new 2020 + 15.years + 3.hours
|
||||
+ : Duration -> Date_Time
|
||||
example_plus = Date_Time.new 2020 + 15.years + (Duration.new hours=3)
|
||||
+ : Duration -> Date_Time ! Time_Error
|
||||
+ self amount =
|
||||
Time_Utils.datetime_adjust self Time_Utils.AdjustOp.PLUS amount.internal_period amount.internal_duration
|
||||
Panic.catch ArithmeticException (self.plus_builtin amount) (err -> Error.throw (Time_Error_Data err.getMessage))
|
||||
|
||||
## Shift the date by the specified amount of business days.
|
||||
|
||||
@ -442,9 +443,9 @@ type Date_Time
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_minus = Date_Time.new 2020 - 1.year - 9.months
|
||||
- : Duration -> Date_Time
|
||||
- : Duration -> Date_Time ! Time_Error
|
||||
- self amount =
|
||||
Time_Utils.datetime_adjust self Time_Utils.AdjustOp.MINUS amount.internal_period amount.internal_duration
|
||||
Panic.catch ArithmeticException (self.minus_builtin amount) (err -> Error.throw (Time_Error_Data err.getMessage))
|
||||
|
||||
## Convert this time to text using the default formatter.
|
||||
|
||||
|
@ -1,17 +1,18 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.System
|
||||
|
||||
polyglot java import java.lang.ArithmeticException
|
||||
polyglot java import java.time.Duration as Java_Duration
|
||||
polyglot java import java.time.Period as Java_Period
|
||||
polyglot java import org.enso.base.Time_Utils
|
||||
polyglot java import java.lang.ArithmeticException
|
||||
|
||||
## Create an interval representing the duration between two points in time.
|
||||
|
||||
Arguments:
|
||||
- start_inclusive: The start time of the duration.
|
||||
- end_inclusive: The end time of the duration.
|
||||
- timezone_aware: Should the creation of the interval be timezone-aware.
|
||||
- start_inclusive: The start datetime of the duration.
|
||||
- end_inclusive: The end datetime of the duration.
|
||||
- timezone_aware: Whether the duration between two given times should be
|
||||
aware of the timezone, that can be set for start or end times.
|
||||
|
||||
> Example
|
||||
An hour interval between two points in time.
|
||||
@ -20,12 +21,40 @@ polyglot java import org.enso.base.Time_Utils
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_between = Duration.between Date_Time.now (Date_Time.new 2010 10 20)
|
||||
between : Date_Time -> Date_Time -> Duration
|
||||
between : Date_Time -> Date_Time -> Boolean -> Duration
|
||||
between start_inclusive end_exclusive timezone_aware=True =
|
||||
period = Java_Period.ofDays 0 . normalized
|
||||
duration = Time_Utils.duration_between start_inclusive end_exclusive timezone_aware
|
||||
Duration_Data period duration
|
||||
Duration.between_builtin start_inclusive end_exclusive timezone_aware
|
||||
|
||||
## Create a duration from time units.
|
||||
|
||||
Arguments:
|
||||
- hours: hours
|
||||
- minutes: minutes
|
||||
- seconds: seconds
|
||||
- milliseconds: milliseconds
|
||||
- nanoseconds: nanoseconds
|
||||
|
||||
> Example
|
||||
Duration of 2 hours.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_duration = Duration.new hours=2
|
||||
new : Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Duration
|
||||
new hours=0 minutes=0 seconds=0 milliseconds=0 nanoseconds=0 =
|
||||
Duration.new_builtin hours minutes seconds milliseconds nanoseconds
|
||||
|
||||
|
||||
## Create a zero (empty) duration.
|
||||
> Example
|
||||
Folding a vector of durations.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
durations = [(Duration.new seconds=1), (Duration.new seconds=2), (Duration.new seconds=3)]
|
||||
example_sum = durations.fold Duration.zero (+)
|
||||
zero : Duration
|
||||
zero = new
|
||||
|
||||
## ADVANCED
|
||||
|
||||
@ -38,25 +67,13 @@ time_execution ~function =
|
||||
start = System.nano_time
|
||||
result = Runtime.no_inline function
|
||||
end = System.nano_time
|
||||
duration = Duration_Data (Java_Period.ofDays 0) (Java_Duration.ofNanos (end - start))
|
||||
duration = new nanoseconds=(end - start)
|
||||
Pair_Data duration result
|
||||
|
||||
|
||||
# TODO Dubious constructor export
|
||||
from project.Data.Time.Duration.Duration import all
|
||||
from project.Data.Time.Duration.Duration export all
|
||||
|
||||
@Builtin_Type
|
||||
type Duration
|
||||
|
||||
## An amount of time in terms of years, months, days, hours, minutes,
|
||||
seconds and nanoseconds.
|
||||
|
||||
Arguments:
|
||||
- internal_period: The internal representation of the time as a period.
|
||||
- internal_duration: The internal representation of the time as a
|
||||
duration.
|
||||
Duration_Data internal_period internal_duration
|
||||
|
||||
## Add the specified amount of time to this duration.
|
||||
|
||||
Arguments:
|
||||
@ -67,19 +84,17 @@ type Duration
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_add = 3.minutes + 6.seconds
|
||||
example_add = (Duration.new minutes=3) + (Duration.new seconds=6)
|
||||
|
||||
> Example
|
||||
Add 12 hours to a duration of a month.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_add = 1.month + 12.hours
|
||||
+ : Duration -> Duration
|
||||
example_add = 1.month + (Duration.new hours=12)
|
||||
+ : Duration -> Duration ! Time_Error
|
||||
+ self that =
|
||||
period = self.internal_period . plus that.internal_period . normalized
|
||||
duration = self.internal_duration . plus that.internal_duration
|
||||
Duration_Data period duration
|
||||
Panic.catch ArithmeticException (self.plus_builtin that) (err-> Error.throw (Time_Error_Data err.getMessage))
|
||||
|
||||
## Subtract the specified amount of time from this duration.
|
||||
|
||||
@ -94,186 +109,14 @@ type Duration
|
||||
example_subtract = 3.years - 11.months
|
||||
|
||||
> Example
|
||||
Substract 30 minutes from a duration of 7 months.
|
||||
Substract 30 minutes from a duration of 6 hours.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_subtract = 7.months - 30.minutes
|
||||
- : Duration -> Duration
|
||||
example_subtract = (Duration.new hours=6) - (Duration.new minutes=30)
|
||||
- : Duration -> Duration ! Time_Error
|
||||
- self that =
|
||||
period = self.internal_period . minus that.internal_period . normalized
|
||||
duration = self.internal_duration . minus that.internal_duration
|
||||
Duration_Data period duration
|
||||
|
||||
## Get the portion of the duration expressed in nanoseconds.
|
||||
|
||||
> Example
|
||||
Get the portion of the duration expressed in nanoseconds.
|
||||
|
||||
import Standard.Examples
|
||||
|
||||
example_nanos = Examples.duration.nanoseconds
|
||||
nanoseconds : Integer
|
||||
nanoseconds self = self.internal_duration . toNanosPart
|
||||
|
||||
## Get the portion of the duration expressed in milliseconds.
|
||||
|
||||
> Example
|
||||
Get the portion of the duration expressed in milliseconds.
|
||||
|
||||
import Standard.Examples
|
||||
|
||||
example_millis = Examples.duration.milliseconds
|
||||
milliseconds : Integer
|
||||
milliseconds self = self.internal_duration . toMillisPart
|
||||
|
||||
## UNSTABLE
|
||||
Convert the duration to total milliseconds.
|
||||
total_milliseconds : Integer ! Illegal_Argument_Error
|
||||
total_milliseconds self =
|
||||
Panic.catch ArithmeticException (self.internal_duration . toMillis) _->
|
||||
Error.throw (Illegal_Argument_Error_Data "The duration is too large to convert it to milliseconds.")
|
||||
|
||||
## Get the portion of the duration expressed in seconds.
|
||||
|
||||
> Example
|
||||
Get the portion of the duration expressed in seconds.
|
||||
|
||||
import Standard.Examples
|
||||
|
||||
example_seconds = Examples.duration.milliseconds
|
||||
seconds : Integer
|
||||
seconds self = self.internal_duration . toSecondsPart
|
||||
|
||||
## Get the portion of the duration expressed in minutes.
|
||||
|
||||
> Example
|
||||
Get the portion of the duration expressed in minutes.
|
||||
|
||||
import Standard.Examples
|
||||
|
||||
example_minutes = Examples.duration.milliseconds
|
||||
minutes : Integer
|
||||
minutes self = self.internal_duration . toMinutesPart
|
||||
|
||||
## Get the portion of the duration expressed in hours.
|
||||
|
||||
> Example
|
||||
Get the portion of the duration expressed in hours.
|
||||
|
||||
import Standard.Examples
|
||||
|
||||
example_hours = Examples.duration.milliseconds
|
||||
hours : Integer
|
||||
hours self = self.internal_duration . toHours
|
||||
|
||||
## Get the portion of the duration expressed in days.
|
||||
|
||||
> Example
|
||||
Get the portion of the duration expressed in days.
|
||||
|
||||
import Standard.Examples
|
||||
|
||||
example_days = Examples.duration.milliseconds
|
||||
days : Integer
|
||||
days self = self.internal_period . getDays
|
||||
|
||||
## Get the portion of the duration expressed in months.
|
||||
|
||||
> Example
|
||||
Get the portion of the duration expressed in months.
|
||||
|
||||
import Standard.Examples
|
||||
|
||||
example_months = Examples.duration.months
|
||||
months : Integer
|
||||
months self = self.internal_period . getMonths
|
||||
|
||||
## Get the portion of the duration expressed in years.
|
||||
|
||||
> Example
|
||||
Get the portion of the duration expressed in years.
|
||||
|
||||
import Standard.Examples
|
||||
|
||||
example_years = Examples.duration.years
|
||||
years : Integer
|
||||
years self = self.internal_period . getYears
|
||||
|
||||
## Convert this duration to a Vector of years, months, days, hours, minutes,
|
||||
seconds and nanosecnods.
|
||||
|
||||
> Example
|
||||
Convert duration of a year and a hour to a vector returning
|
||||
`[1, 0, 0, 1, 0, 0, 0]`.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_to_vec = (1.year + 1.hour).to_vector
|
||||
|
||||
> Example
|
||||
Convert duration of 800 nanoseconds to a vector returning
|
||||
`[0, 0, 0, 0, 0, 0, 800]`
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_to_vec = 800.nanoseconds . to_vector
|
||||
to_vector : Vector.Vector Integer
|
||||
to_vector self = [self.years, self.months, self.days, self.hours, self.minutes, self.seconds, self.nanoseconds]
|
||||
|
||||
## A Duration to Json conversion.
|
||||
|
||||
> Example
|
||||
Convert a duration of 10 seconds to Json.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_to_json = 10.seconds.to_json
|
||||
to_json : Json.Object
|
||||
to_json self =
|
||||
b = Vector.new_builder
|
||||
b.append ["type", "Duration"]
|
||||
if self.years==0 . not then b.append ["years", self.years]
|
||||
if self.months==0 . not then b.append ["months", self.months]
|
||||
if self.days==0 . not then b.append ["days", self.days]
|
||||
if self.hours==0 . not then b.append ["hours", self.hours]
|
||||
if self.minutes==0 . not then b.append ["minutes", self.minutes]
|
||||
if self.seconds==0 . not then b.append ["seconds", self.seconds]
|
||||
if self.nanoseconds==0 . not then b.append ["nanoseconds", self.nanoseconds]
|
||||
Json.from_pairs b.to_vector
|
||||
|
||||
## Check if this duration is date-based.
|
||||
|
||||
> Example
|
||||
Check if the duration of 10 seconds is date-based.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_is_date = 10.seconds.is_date
|
||||
is_date : Boolean
|
||||
is_date self = (self.years==0 . not) || (self.months==0 . not) || (self.days==0 . not)
|
||||
|
||||
## Check if this duration is time-based.
|
||||
|
||||
> Example
|
||||
Check if the duration of 10 seconds is time-based.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_is_time = 10.seconds.is_time
|
||||
is_time : Boolean
|
||||
is_time self = (self.hours==0 . not) || (self.minutes==0 . not) || (self.seconds==0 . not) || (self.nanoseconds==0 . not)
|
||||
|
||||
## Check if this duration represents an empty time-span.
|
||||
|
||||
> Example
|
||||
Check if the duration of 10 seconds is empty.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_is_empty = 10.seconds.is_empty
|
||||
is_empty : Boolean
|
||||
is_empty self = self.is_date.not && self.is_time.not
|
||||
Panic.catch ArithmeticException (self.minus_builtin that) (err -> Error.throw (Time_Error_Data err.getMessage))
|
||||
|
||||
## Check two durations for equality.
|
||||
|
||||
@ -285,9 +128,9 @@ type Duration
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_eq = 60.seconds == 1.minute
|
||||
example_eq = (Duration.new seconds=60).total_minutes == (Duration.new minutes=1).total_minutes
|
||||
== : Duration -> Boolean
|
||||
== self that = self.to_vector == that.to_vector
|
||||
== self that = self.equals_builtin that
|
||||
|
||||
## Compares `self` to `that` to produce an ordering.
|
||||
|
||||
@ -300,193 +143,136 @@ type Duration
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_compare_to =
|
||||
duration_1 = 1.year
|
||||
duration_2 = 12.months + 1.day
|
||||
duration_1 = (Duration.new hour=1)
|
||||
duration_2 = (Duration.new minutes=60) + (Duration.new minutes=5)
|
||||
duration_1.compare_to duration_2
|
||||
compare_to : Duration -> Ordering
|
||||
compare_to self that =
|
||||
if self.years > that.years then Ordering.Greater else
|
||||
if self.years < that.years then Ordering.Less else
|
||||
if self.months > that.months then Ordering.Greater else
|
||||
if self.months < that.months then Ordering.Less else
|
||||
if self.days > that.days then Ordering.Greater else
|
||||
if self.days < that.days then Ordering.Less else
|
||||
duration_sign = self.internal_duration.compareTo that.internal_duration
|
||||
Ordering.from_sign duration_sign
|
||||
compare_to self that = Ordering.from_sign (self.compare_to_builtin that)
|
||||
|
||||
## Create a duration of `self` nanoseconds.
|
||||
## Get the portion of the duration expressed in nanoseconds.
|
||||
|
||||
> Examples
|
||||
Create a duration of 1 nanosecond.
|
||||
> Example
|
||||
Get the portion of the duration expressed in nanoseconds.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
import Standard.Examples
|
||||
|
||||
example_nano = 1.nanosecond
|
||||
Integer.nanosecond : Duration
|
||||
Integer.nanosecond self = Duration_Data (Java_Period.ofDays 0) (Java_Duration.ofNanos self)
|
||||
example_nanos = Examples.duration.nanoseconds
|
||||
nanoseconds : Integer
|
||||
nanoseconds self = @Builtin_Method "Duration.nanoseconds"
|
||||
|
||||
## Create a duration of `self` nanoseconds.
|
||||
## Get the portion of the duration expressed in milliseconds.
|
||||
|
||||
> Examples
|
||||
Create a duration of 20 nanoseconds.
|
||||
> Example
|
||||
Get the portion of the duration expressed in milliseconds.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
import Standard.Examples
|
||||
|
||||
example_nano = 20.nanoseconds
|
||||
Integer.nanoseconds : Duration
|
||||
Integer.nanoseconds self = self.nanosecond
|
||||
example_millis = Examples.duration.milliseconds
|
||||
milliseconds : Integer
|
||||
milliseconds self = @Builtin_Method "Duration.milliseconds"
|
||||
|
||||
## Create a duration of `self` milliseconds.
|
||||
## Get the portion of the duration expressed in seconds.
|
||||
|
||||
> Example
|
||||
Create a duration of 1 millisecond.
|
||||
> Example
|
||||
Get the portion of the duration expressed in seconds.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
import Standard.Examples
|
||||
|
||||
example_milli = 1.millisecond
|
||||
Integer.millisecond : Duration
|
||||
Integer.millisecond self = Duration_Data (Java_Period.ofDays 0) (Java_Duration.ofMillis self)
|
||||
example_seconds = Examples.duration.seconds
|
||||
seconds : Integer
|
||||
seconds self = @Builtin_Method "Duration.seconds"
|
||||
|
||||
## Create a duration of `self` milliseconds.
|
||||
## Get the portion of the duration expressed in minutes.
|
||||
|
||||
> Example
|
||||
Create a duration of 20 milliseconds.
|
||||
> Example
|
||||
Get the portion of the duration expressed in minutes.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
import Standard.Examples
|
||||
|
||||
example_milli = 20.milliseconds
|
||||
Integer.milliseconds : Duration
|
||||
Integer.milliseconds self = self.millisecond
|
||||
example_minutes = Examples.duration.minutes
|
||||
minutes : Integer
|
||||
minutes self = @Builtin_Method "Duration.minutes"
|
||||
|
||||
## Create a duration of `self` seconds.
|
||||
## Get the portion of the duration expressed in hours.
|
||||
|
||||
> Example
|
||||
Create a duration of 1 second.
|
||||
> Example
|
||||
Get the portion of the duration expressed in hours.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
import Standard.Examples
|
||||
|
||||
example_second = 1.second
|
||||
Integer.second : Duration
|
||||
Integer.second self = Duration_Data (Java_Period.ofDays 0) (Java_Duration.ofSeconds self)
|
||||
example_hours = Examples.duration.milliseconds
|
||||
hours : Integer
|
||||
hours self = @Builtin_Method "Duration.hours"
|
||||
|
||||
## Create a duration of `self` seconds.
|
||||
## UNSTABLE
|
||||
Convert the duration to total milliseconds.
|
||||
total_milliseconds : Integer ! Illegal_State_Error
|
||||
total_milliseconds self =
|
||||
Panic.catch ArithmeticException (self.total_milliseconds_builtin) _->
|
||||
Error.throw (Illegal_State_Error_Data "The duration is too large to convert it to milliseconds")
|
||||
|
||||
> Example
|
||||
Create a duration of 20 seconds.
|
||||
## UNSTABLE
|
||||
Convert the duration to total seconds.
|
||||
total_seconds : Decimal ! Illegal_State_Error
|
||||
total_seconds self = self.total_milliseconds / 1000.0
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
## UNSTABLE
|
||||
Convert the duration to total minutes.
|
||||
total_minutes : Decimal ! Illegal_State_Error
|
||||
total_minutes self = self.total_seconds / 60.0
|
||||
|
||||
example_second = 20.seconds
|
||||
Integer.seconds : Duration
|
||||
Integer.seconds self = self.second
|
||||
## UNSTABLE
|
||||
Convert the duration to total minutes.
|
||||
total_hours : Decimal ! Illegal_State_Error
|
||||
total_hours self = self.total_minutes / 60.0
|
||||
|
||||
## Create a duration of `self` minutes.
|
||||
## Convert this duration to a Vector of hours, minutes, seconds, milliseconds
|
||||
and nanoseconds.
|
||||
|
||||
> Example
|
||||
Create a duration of 1 minute.
|
||||
> Example
|
||||
Convert a duration of one hour to a vector resulting in
|
||||
`[1, 0, 30, 0, 0]`.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_min = 1.minute
|
||||
Integer.minute : Duration
|
||||
Integer.minute self = Duration_Data (Java_Period.ofDays 0) (Java_Duration.ofMinutes self)
|
||||
example_to_vec = (Duration.new hours=1 seconds=30).to_vector
|
||||
|
||||
## Create a duration of `self` minutes.
|
||||
> Example
|
||||
Convert duration of 800 nanoseconds to a vector returning
|
||||
`[0, 0, 0, 0, 0, 800]`
|
||||
|
||||
> Example
|
||||
Create a duration of 20 minutes.
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
example_to_vec = (Duration.new nanoseconds=800)).to_vector
|
||||
to_vector : Vector.Vector Integer
|
||||
to_vector self = [self.hours, self.minutes, self.seconds, self.milliseconds, self.nanoseconds]
|
||||
|
||||
example_min = 20.minutes
|
||||
Integer.minutes : Duration
|
||||
Integer.minutes self = self.minute
|
||||
## A Duration to Json conversion.
|
||||
|
||||
## Create a duration of `self` hours.
|
||||
> Example
|
||||
Convert a duration of 10 seconds to Json.
|
||||
|
||||
> Example
|
||||
Create a duration of 1 hour.
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
example_to_json = (Duration.new seconds=10).to_json
|
||||
to_json : Json.Object
|
||||
to_json self =
|
||||
b = Vector.new_builder
|
||||
b.append ["type", "Duration"]
|
||||
if self.hours==0 . not then b.append ["hours", self.hours]
|
||||
if self.minutes==0 . not then b.append ["minutes", self.minutes]
|
||||
if self.seconds==0 . not then b.append ["seconds", self.seconds]
|
||||
if self.milliseconds==0 . not then b.append ["milliseconds", self.milliseconds]
|
||||
if self.nanoseconds==0 . not then b.append ["nanoseconds", self.nanoseconds]
|
||||
Json.from_pairs b.to_vector
|
||||
|
||||
example_hour = 1.hour
|
||||
Integer.hour : Duration
|
||||
Integer.hour self = Duration_Data (Java_Period.ofDays 0) (Java_Duration.ofHours self)
|
||||
## Check if this duration represents an empty time-span.
|
||||
|
||||
## Create a duration of `self` hours.
|
||||
> Example
|
||||
Check if the duration of 10 seconds is empty.
|
||||
|
||||
> Example
|
||||
Create a duration of 20 hours.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_hour = 20.hours
|
||||
Integer.hours : Duration
|
||||
Integer.hours self = self.hour
|
||||
|
||||
## Create a duration of `self` days.
|
||||
|
||||
> Example
|
||||
Create a duration of 1 day.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_day = 1.day
|
||||
Integer.day : Duration
|
||||
Integer.day self = Duration_Data (Java_Period.ofDays self . normalized) (Java_Duration.ofSeconds 0)
|
||||
|
||||
## Create a duration of `self` days.
|
||||
|
||||
> Example
|
||||
Create a duration of 20 days.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_day = 20.days
|
||||
Integer.days : Duration
|
||||
Integer.days self = self.day
|
||||
|
||||
## Create a duration of `self` months.
|
||||
|
||||
> Example
|
||||
Create a duration of 1 month.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_month = 1.month
|
||||
Integer.month : Duration
|
||||
Integer.month self = Duration_Data (Java_Period.ofMonths self . normalized) (Java_Duration.ofSeconds 0)
|
||||
|
||||
## Create a duration of `self` months.
|
||||
|
||||
> Example
|
||||
Create a duration of 6 months.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_month = 6.months
|
||||
Integer.months : Duration
|
||||
Integer.months self = self.month
|
||||
|
||||
## Create a duration of `self` years.
|
||||
|
||||
> Example
|
||||
Create a duration of 1 year.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_year = 1.year
|
||||
Integer.year : Duration
|
||||
Integer.year self = Duration_Data (Java_Period.ofYears self . normalized) (Java_Duration.ofSeconds 0)
|
||||
|
||||
## Create a duration of `self` years.
|
||||
|
||||
> Example
|
||||
Create a duration of 20 years.
|
||||
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_year = 20.years
|
||||
Integer.years : Duration
|
||||
Integer.years self = self.year
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_is_empty = 10.seconds.is_empty
|
||||
is_empty : Boolean
|
||||
is_empty self = self.to_vector . all (==0)
|
||||
|
@ -215,10 +215,9 @@ type Time_Of_Day
|
||||
from Standard.Base import Time_Of_Day
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_plus = Time_Of_Day.new + 3.seconds
|
||||
example_plus = Time_Of_Day.new + (Duration.new seconds=3)
|
||||
+ : Duration -> Time_Of_Day
|
||||
+ self amount = if amount.is_date then Error.throw (Time_Error_Data "Time_Of_Day does not support date intervals") else
|
||||
Time_Utils.time_adjust self Time_Utils.AdjustOp.PLUS amount.internal_duration
|
||||
+ self amount = self.plus_builtin amount
|
||||
|
||||
## Subtract the specified amount of time from this instant to get a new
|
||||
instant.
|
||||
@ -232,10 +231,9 @@ type Time_Of_Day
|
||||
from Standard.Base import Time_Of_Day
|
||||
import Standard.Base.Data.Time.Duration
|
||||
|
||||
example_minus = Time_Of_Day.now - 12.hours
|
||||
example_minus = Time_Of_Day.now - (Duration.new hours=12)
|
||||
- : Duration -> Time_Of_Day
|
||||
- self amount = if amount.is_date then Error.throw (Time_Error_Data "Time_Of_Day does not support date intervals") else
|
||||
Time_Utils.time_adjust self Time_Utils.AdjustOp.MINUS amount.internal_duration
|
||||
- self amount = self.minus_builtin amount
|
||||
|
||||
## Format this time of day as text using the default formatter.
|
||||
|
||||
|
@ -36,7 +36,7 @@ polyglot java import org.enso.base.Http_Utils
|
||||
|
||||
> Example
|
||||
Create an HTTP client with extended timeout.
|
||||
Http.new timeout=30.seconds
|
||||
Http.new timeout=(Duration.new seconds=30)
|
||||
|
||||
> Example
|
||||
Create an HTTP client with extended timeout and proxy settings.
|
||||
@ -48,7 +48,7 @@ polyglot java import org.enso.base.Http_Utils
|
||||
example_new =
|
||||
Http.new (timeout = 30.seconds) (proxy = Proxy.new "example.com" 8080)
|
||||
new : Duration -> Boolean -> Proxy -> Http
|
||||
new (timeout = 10.seconds) (follow_redirects = True) (proxy = Proxy.System) (version = Version.Http_1_1) =
|
||||
new (timeout = (Duration.new seconds=10)) (follow_redirects = True) (proxy = Proxy.System) (version = Version.Http_1_1) =
|
||||
Http_Data timeout follow_redirects proxy version
|
||||
|
||||
## Send an Options request.
|
||||
@ -662,9 +662,7 @@ type Http
|
||||
internal_http_client : HttpClient
|
||||
internal_http_client self =
|
||||
builder = HttpClient.newBuilder
|
||||
# timeout
|
||||
if self.timeout.is_date then Panic.throw (Time_Error_Data "Connection timeout does not support date intervals") else
|
||||
builder.connectTimeout self.timeout.internal_duration
|
||||
builder.connectTimeout self.timeout
|
||||
# redirect
|
||||
redirect = HttpClient.Redirect
|
||||
redirect_policy = case self.follow_redirects of
|
||||
|
@ -165,7 +165,7 @@ get_geo_data = Http.fetch geo_data_url
|
||||
|
||||
## A simple HTTP client for examples.
|
||||
http_client : Http
|
||||
http_client = Http.new (timeout = 30.seconds)
|
||||
http_client = Http.new (timeout = Duration.new seconds=30)
|
||||
|
||||
## A basic URI for examples.
|
||||
uri : URI
|
||||
|
@ -166,7 +166,7 @@ specify : Text -> Any -> (Text | Nothing) -> Nothing
|
||||
specify label ~behavior pending=Nothing =
|
||||
pair = case pending of
|
||||
Nothing -> Duration.time_execution (run_spec behavior)
|
||||
reason -> Pair_Data 0.milliseconds (Pending reason)
|
||||
reason -> Pair_Data Duration.zero (Pending reason)
|
||||
result = pair.second
|
||||
time_taken = pair.first
|
||||
spec = State.get Spec
|
||||
@ -838,14 +838,14 @@ report_pending_group name reason config builder =
|
||||
Prints a report on the tests to standard output.
|
||||
Spec.print_report : Suite_Config -> (StringBuilder|Nothing) -> Nothing
|
||||
Spec.print_report self config builder =
|
||||
total_time = self.behaviors.fold 0.milliseconds acc-> behavior->
|
||||
total_time = self.behaviors.fold Duration.zero acc-> behavior->
|
||||
acc + behavior.time_taken
|
||||
if config.should_output_junit then
|
||||
builder.append (' <testsuite name="' + (escape_xml self.name) + '" timestamp="' + (Date_Time.now.format "yyyy-MM-dd'T'HH:mm:ss") + '"')
|
||||
builder.append (' tests="' + self.behaviors.length.to_text + '"')
|
||||
builder.append (' disabled="' + self.behaviors.filter (x->(x.is_a Pending)) . length . to_text + '"')
|
||||
builder.append (' errors="' + self.behaviors.filter (x->(x.is_a Failure)) . length . to_text + '"')
|
||||
builder.append (' time="' + (total_time.total_milliseconds / 1000.0).to_text + '"')
|
||||
builder.append (' time="' + (total_time.total_seconds).to_text + '"')
|
||||
builder.append ('>\n')
|
||||
|
||||
self.behaviors.reverse.each behavior->
|
||||
|
@ -111,6 +111,13 @@ For example, to update settings for the Launcher:
|
||||
java -agentlib:native-image-agent=config-merge-dir=engine/launcher/src/main/resources/META-INF/native-image/org/enso/launcher -jar launcher.jar <arguments>
|
||||
```
|
||||
|
||||
Note that for convenience, you can run the launcher/engine runner via
|
||||
`bin/enso`, e.g.
|
||||
|
||||
```bash
|
||||
env JAVA_OPTS="-agentlib:native-image-agent=config-merge-dir=./engine/runner-native/src/main/resources/META-INF/native-image/org/enso/runner" ./built-distribution/enso-engine-0.0.0-dev-linux-amd64/enso-0.0.0-dev/bin/enso --run tmp.enso
|
||||
```
|
||||
|
||||
The command may need to be re-run with different arguments to ensure that all
|
||||
execution paths that use reflection are covered. The configuration files between
|
||||
consecutive runs will be merged (a warning may be issued for the first run if
|
||||
|
@ -261,6 +261,90 @@
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.ToTextTimeOfDayMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.MinusBuiltinTimeOfDayMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.MillisecondsDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.MinusBuiltinDateTimeMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.MinusBuiltinDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.BetweenBuiltinDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.CompareToBuiltinDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.TotalMillisecondsBuiltinDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.Duration",
|
||||
"methods":[{"name":"<init>","parameterTypes":[] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.EqualsBuiltinDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.HoursDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.MillisecondsDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.MinutesDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.MinusBuiltinDateTimeMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.MinusBuiltinDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.MinusBuiltinTimeOfDayMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.NanosecondsDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.NewBuiltinDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.PlusBuiltinDateTimeMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.PlusBuiltinDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.PlusBuiltinTimeOfDayMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.SecondsDurationMethodGen",
|
||||
"methods":[{"name":"makeFunction","parameterTypes":["org.enso.interpreter.Language"] }]}
|
||||
,
|
||||
{
|
||||
"name":"org.enso.interpreter.node.expression.builtin.date.ToTextTimeZoneMethodGen",
|
||||
|
@ -18,7 +18,7 @@ import java.util.Arrays;
|
||||
* in EPB because EPB is a dependency of runtime.
|
||||
*/
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
public class ReadOnlyArray implements TruffleObject {
|
||||
public final class ReadOnlyArray implements TruffleObject {
|
||||
|
||||
private final Object[] items;
|
||||
|
||||
|
@ -27,7 +27,7 @@ import org.enso.interpreter.epb.node.ContextRewrapNode;
|
||||
* org.enso.interpreter.epb.EpbLanguage} for the explanation of this system.
|
||||
*/
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
public class PolyglotProxy implements TruffleObject {
|
||||
public final class PolyglotProxy implements TruffleObject {
|
||||
final Object delegate;
|
||||
private final GuardedTruffleContext origin;
|
||||
private final GuardedTruffleContext target;
|
||||
|
@ -54,7 +54,7 @@ public class FunctionCallInstrumentationNode extends Node implements Instrumenta
|
||||
|
||||
/** A simple value class for function call information. */
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
public static class FunctionCall implements TruffleObject {
|
||||
public static final class FunctionCall implements TruffleObject {
|
||||
private final Function function;
|
||||
private final Object state;
|
||||
private final @CompilerDirectives.CompilationFinal(dimensions = 1) Object[] arguments;
|
||||
|
@ -14,11 +14,6 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
||||
import com.oracle.truffle.api.profiles.ConditionProfile;
|
||||
import com.oracle.truffle.api.source.SourceSection;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
|
||||
import org.enso.interpreter.node.BaseNode;
|
||||
import org.enso.interpreter.node.callable.dispatch.InvokeFunctionNode;
|
||||
import org.enso.interpreter.node.callable.resolver.HostMethodCallNode;
|
||||
@ -28,12 +23,24 @@ import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
|
||||
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
|
||||
import org.enso.interpreter.runtime.callable.function.Function;
|
||||
import org.enso.interpreter.runtime.data.*;
|
||||
import org.enso.interpreter.runtime.data.ArrayRope;
|
||||
import org.enso.interpreter.runtime.data.EnsoDate;
|
||||
import org.enso.interpreter.runtime.data.EnsoDateTime;
|
||||
import org.enso.interpreter.runtime.data.EnsoDuration;
|
||||
import org.enso.interpreter.runtime.data.EnsoTimeOfDay;
|
||||
import org.enso.interpreter.runtime.data.EnsoTimeZone;
|
||||
import org.enso.interpreter.runtime.data.text.Text;
|
||||
import org.enso.interpreter.runtime.error.*;
|
||||
import org.enso.interpreter.runtime.error.DataflowError;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.error.PanicSentinel;
|
||||
import org.enso.interpreter.runtime.error.Warning;
|
||||
import org.enso.interpreter.runtime.error.WithWarnings;
|
||||
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||
import org.enso.interpreter.runtime.state.Stateful;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
@ -318,6 +325,35 @@ public abstract class InvokeMethodNode extends BaseNode {
|
||||
}
|
||||
}
|
||||
|
||||
@Specialization(
|
||||
guards = {
|
||||
"!types.hasType(self)",
|
||||
"!types.hasSpecialDispatch(self)",
|
||||
"getPolyglotCallType(self, symbol, interop) == CONVERT_TO_DURATION"
|
||||
})
|
||||
Stateful doConvertDuration(
|
||||
VirtualFrame frame,
|
||||
Object state,
|
||||
UnresolvedSymbol symbol,
|
||||
Object self,
|
||||
Object[] arguments,
|
||||
@CachedLibrary(limit = "10") TypesLibrary types,
|
||||
@CachedLibrary(limit = "10") InteropLibrary interop,
|
||||
@Cached MethodResolverNode methodResolverNode) {
|
||||
var ctx = Context.get(this);
|
||||
try {
|
||||
var duration = interop.asDuration(self);
|
||||
var ensoDuration = new EnsoDuration(duration);
|
||||
Function function =
|
||||
methodResolverNode.expectNonNull(ensoDuration, ctx.getBuiltins().duration(), symbol);
|
||||
|
||||
arguments[0] = ensoDuration;
|
||||
return invokeFunctionNode.execute(function, frame, state, arguments);
|
||||
} catch (UnsupportedMessageException e) {
|
||||
throw new PanicException(ctx.getBuiltins().error().makeNoSuchMethodError(self, symbol), this);
|
||||
}
|
||||
}
|
||||
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
private ZonedDateTime dateTime(LocalDate date, LocalTime time) {
|
||||
return date.atTime(time).atZone(ZoneId.systemDefault());
|
||||
|
@ -1,7 +1,15 @@
|
||||
package org.enso.interpreter.node.callable.resolver;
|
||||
|
||||
import com.oracle.truffle.api.dsl.*;
|
||||
import com.oracle.truffle.api.interop.*;
|
||||
import com.oracle.truffle.api.dsl.Cached;
|
||||
import com.oracle.truffle.api.dsl.GenerateUncached;
|
||||
import com.oracle.truffle.api.dsl.ImportStatic;
|
||||
import com.oracle.truffle.api.dsl.ReportPolymorphism;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.interop.ArityException;
|
||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||
import com.oracle.truffle.api.interop.UnknownIdentifierException;
|
||||
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
||||
import com.oracle.truffle.api.interop.UnsupportedTypeException;
|
||||
import com.oracle.truffle.api.library.CachedLibrary;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import com.oracle.truffle.api.profiles.BranchProfile;
|
||||
@ -57,6 +65,11 @@ public abstract class HostMethodCallNode extends Node {
|
||||
* Standard.Base.Data.Time.Date_Time} with a system Time_Zone and dispatching natively.
|
||||
*/
|
||||
CONVERT_TO_DATE_TIME,
|
||||
/**
|
||||
* The method call should be handled by converting {@code self} to a {@code
|
||||
* Standard.Base.Data.Time.Duration} and dispatching natively.
|
||||
*/
|
||||
CONVERT_TO_DURATION,
|
||||
/**
|
||||
* The method call should be handled by converting {@code self} to a {@code
|
||||
* Standard.Base.Data.Time.Time_Of_Day} and dispatching natively.
|
||||
@ -83,6 +96,7 @@ public abstract class HostMethodCallNode extends Node {
|
||||
&& this != CONVERT_TO_TEXT
|
||||
&& this != CONVERT_TO_DATE
|
||||
&& this != CONVERT_TO_DATE_TIME
|
||||
&& this != CONVERT_TO_DURATION
|
||||
&& this != CONVERT_TO_ZONED_DATE_TIME
|
||||
&& this != CONVERT_TO_TIME_OF_DAY
|
||||
&& this != CONVERT_TO_TIME_ZONE;
|
||||
@ -134,6 +148,8 @@ public abstract class HostMethodCallNode extends Node {
|
||||
}
|
||||
} else if (library.isTime(self)) {
|
||||
return PolyglotCallType.CONVERT_TO_TIME_OF_DAY;
|
||||
} else if (library.isDuration(self)) {
|
||||
return PolyglotCallType.CONVERT_TO_DURATION;
|
||||
} else if (library.isTimeZone(self)) {
|
||||
return PolyglotCallType.CONVERT_TO_TIME_ZONE;
|
||||
} else if (library.isString(self)) {
|
||||
|
@ -46,7 +46,7 @@ import scala.Function1;
|
||||
|
||||
/** Represents a source module with a known location. */
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
public class Module implements TruffleObject {
|
||||
public final class Module implements TruffleObject {
|
||||
|
||||
/** Defines a stage of compilation of the module. */
|
||||
public enum CompilationStage {
|
||||
|
@ -88,6 +88,7 @@ public class Builtins {
|
||||
private final Builtin file;
|
||||
private final Builtin date;
|
||||
private final Builtin dateTime;
|
||||
private final Builtin duration;
|
||||
private final Builtin timeOfDay;
|
||||
private final Builtin timeZone;
|
||||
private final Builtin warning;
|
||||
@ -129,6 +130,7 @@ public class Builtins {
|
||||
file = builtins.get(File.class);
|
||||
date = builtins.get(org.enso.interpreter.node.expression.builtin.date.Date.class);
|
||||
dateTime = builtins.get(org.enso.interpreter.node.expression.builtin.date.DateTime.class);
|
||||
duration = builtins.get(org.enso.interpreter.node.expression.builtin.date.Duration.class);
|
||||
timeOfDay = builtins.get(org.enso.interpreter.node.expression.builtin.date.TimeOfDay.class);
|
||||
timeZone = builtins.get(org.enso.interpreter.node.expression.builtin.date.TimeZone.class);
|
||||
special = new Special(language);
|
||||
@ -457,6 +459,15 @@ public class Builtins {
|
||||
return timeOfDay.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code Duration} atom constructor.
|
||||
*
|
||||
* @return the {@code Duration} atom constructor.
|
||||
*/
|
||||
public Type duration() {
|
||||
return duration.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code TimeZone} atom constructor.
|
||||
*
|
||||
|
@ -15,7 +15,7 @@ import org.enso.interpreter.runtime.state.data.EmptyMap;
|
||||
|
||||
/** Simple runtime value representing a yet-unresolved by-name symbol. */
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
public class UnresolvedConversion implements TruffleObject {
|
||||
public final class UnresolvedConversion implements TruffleObject {
|
||||
private final ModuleScope scope;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ import org.enso.interpreter.runtime.state.data.EmptyMap;
|
||||
|
||||
/** Simple runtime value representing a yet-unresolved by-name symbol. */
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
public class UnresolvedSymbol implements TruffleObject {
|
||||
public final class UnresolvedSymbol implements TruffleObject {
|
||||
private final String name;
|
||||
private final ModuleScope scope;
|
||||
|
||||
|
@ -12,7 +12,7 @@ import com.oracle.truffle.api.library.ExportMessage;
|
||||
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
|
||||
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
class ArraySlice implements TruffleObject {
|
||||
public final class ArraySlice implements TruffleObject {
|
||||
private final Object storage;
|
||||
private final long start;
|
||||
private final long end;
|
||||
|
@ -3,20 +3,26 @@ package org.enso.interpreter.runtime.data;
|
||||
import com.oracle.truffle.api.CompilerDirectives;
|
||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||
import com.oracle.truffle.api.interop.TruffleObject;
|
||||
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
||||
import com.oracle.truffle.api.library.CachedLibrary;
|
||||
import com.oracle.truffle.api.library.ExportLibrary;
|
||||
import com.oracle.truffle.api.library.ExportMessage;
|
||||
import org.enso.interpreter.dsl.Builtin;
|
||||
import org.enso.interpreter.node.expression.builtin.error.PolyglotError;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.data.text.Text;
|
||||
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||
|
||||
import java.time.*;
|
||||
import java.time.DateTimeException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import org.enso.interpreter.dsl.Builtin;
|
||||
import org.enso.interpreter.node.expression.builtin.error.PolyglotError;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.data.text.Text;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
@ExportLibrary(TypesLibrary.class)
|
||||
@ -138,6 +144,24 @@ public final class EnsoDateTime implements TruffleObject {
|
||||
return new EnsoTimeZone(dateTime.getZone());
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "plus_builtin", description = "Adds a duration to this date time")
|
||||
@Builtin.Specialize
|
||||
@Builtin.WrapException(from = UnsupportedMessageException.class, to = PanicException.class)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public EnsoDateTime plus(Object durationObject, InteropLibrary interop)
|
||||
throws UnsupportedMessageException {
|
||||
return new EnsoDateTime(dateTime.plus(interop.asDuration(durationObject)));
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "minus_builtin", description = "Subtracts a duration from this date time")
|
||||
@Builtin.Specialize
|
||||
@Builtin.WrapException(from = UnsupportedMessageException.class, to = PanicException.class)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public EnsoDateTime minus(Object durationObject, InteropLibrary interop)
|
||||
throws UnsupportedMessageException {
|
||||
return new EnsoDateTime(dateTime.minus(interop.asDuration(durationObject)));
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Return the number of seconds from the Unix epoch.")
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public long toEpochSeconds() {
|
||||
|
@ -0,0 +1,195 @@
|
||||
package org.enso.interpreter.runtime.data;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives;
|
||||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||
import com.oracle.truffle.api.interop.TruffleObject;
|
||||
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
||||
import com.oracle.truffle.api.library.CachedLibrary;
|
||||
import com.oracle.truffle.api.library.ExportLibrary;
|
||||
import com.oracle.truffle.api.library.ExportMessage;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.Temporal;
|
||||
import org.enso.interpreter.dsl.Builtin;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
@ExportLibrary(TypesLibrary.class)
|
||||
@Builtin(pkg = "date", name = "Duration", stdlibName = "Standard.Base.Data.Time.Duration")
|
||||
public final class EnsoDuration implements TruffleObject {
|
||||
private final Duration duration;
|
||||
|
||||
public EnsoDuration(Duration duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
boolean hasType() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
Type getType(@CachedLibrary("this") TypesLibrary thisLib) {
|
||||
return Context.get(thisLib).getBuiltins().duration();
|
||||
}
|
||||
|
||||
@Builtin.Method(
|
||||
name = "new_builtin",
|
||||
description =
|
||||
"Constructs a new Duration from hours, minutes, seconds, milliseconds and nanoseconds")
|
||||
@TruffleBoundary
|
||||
public static EnsoDuration create(
|
||||
long hours, long minutes, long seconds, long milliseconds, long nanoseconds) {
|
||||
var duration =
|
||||
Duration.ofHours(hours)
|
||||
.plusMinutes(minutes)
|
||||
.plusSeconds(seconds)
|
||||
.plusMillis(milliseconds)
|
||||
.plusNanos(nanoseconds);
|
||||
return new EnsoDuration(duration);
|
||||
}
|
||||
|
||||
@Builtin.Method(
|
||||
name = "between_builtin",
|
||||
description =
|
||||
"Construct a new Duration that is between the given start date inclusive, and end date exclusive")
|
||||
@Builtin.Specialize
|
||||
@TruffleBoundary
|
||||
public static EnsoDuration between(
|
||||
Object startInclusive, Object endExclusive, boolean timeZoneAware, InteropLibrary interop) {
|
||||
if (!isDateTime(startInclusive, interop)
|
||||
|| (timeZoneAware && !hasTimeZone(startInclusive, interop))) {
|
||||
throw createNotDateTimePanic("start_inclusive", startInclusive, interop);
|
||||
}
|
||||
if (!isDateTime(endExclusive, interop)
|
||||
|| (timeZoneAware && !hasTimeZone(endExclusive, interop))) {
|
||||
throw createNotDateTimePanic("end_exclusive", endExclusive, interop);
|
||||
}
|
||||
Temporal startTime = convertToDateTime(startInclusive, timeZoneAware, interop);
|
||||
Temporal endTime = convertToDateTime(endExclusive, timeZoneAware, interop);
|
||||
return new EnsoDuration(Duration.between(startTime, endTime));
|
||||
}
|
||||
|
||||
private static boolean isDateTime(Object dateTime, InteropLibrary interop) {
|
||||
return interop.isDate(dateTime) && interop.isTime(dateTime);
|
||||
}
|
||||
|
||||
private static boolean hasTimeZone(Object dateTime, InteropLibrary interop) {
|
||||
return interop.isTimeZone(dateTime);
|
||||
}
|
||||
|
||||
private static PanicException createNotDateTimePanic(
|
||||
String varName, Object object, InteropLibrary interop) {
|
||||
return new PanicException(
|
||||
Context.get(interop).getBuiltins().error().makeTypeError("Date_Time", object, varName),
|
||||
interop);
|
||||
}
|
||||
|
||||
private static Temporal convertToDateTime(
|
||||
Object dateTimeObject, boolean timeZoneAware, InteropLibrary interop) {
|
||||
assert interop.isDate(dateTimeObject);
|
||||
assert interop.isTime(dateTimeObject);
|
||||
try {
|
||||
LocalDate date = interop.asDate(dateTimeObject);
|
||||
LocalTime time = interop.asTime(dateTimeObject);
|
||||
if (timeZoneAware) {
|
||||
assert interop.isTime(dateTimeObject);
|
||||
ZoneId zone = interop.asTimeZone(dateTimeObject);
|
||||
return ZonedDateTime.of(date, time, zone);
|
||||
} else {
|
||||
return LocalDateTime.of(date, time);
|
||||
}
|
||||
} catch (UnsupportedMessageException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Gets the hours part")
|
||||
public long hours() {
|
||||
return duration.toHoursPart();
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Gets the minutes part")
|
||||
public long minutes() {
|
||||
return duration.toMinutesPart();
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Gets the seconds part")
|
||||
public long seconds() {
|
||||
return duration.toSecondsPart();
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Gets the milliseconds part")
|
||||
public long milliseconds() {
|
||||
return duration.toMillisPart();
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Gets the nanoseconds part")
|
||||
public long nanoseconds() {
|
||||
return duration.toNanosPart();
|
||||
}
|
||||
|
||||
@Builtin.Method(
|
||||
name = "total_milliseconds_builtin",
|
||||
description = "Gets the total amount of milliseconds")
|
||||
public long totalMilliseconds() {
|
||||
return duration.toMillis();
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "plus_builtin", description = "Adds another Duration")
|
||||
@Builtin.Specialize
|
||||
@Builtin.WrapException(from = UnsupportedMessageException.class, to = PanicException.class)
|
||||
@TruffleBoundary
|
||||
public EnsoDuration plus(Object durationObject, InteropLibrary interop)
|
||||
throws UnsupportedMessageException {
|
||||
return new EnsoDuration(duration.plus(interop.asDuration(durationObject)));
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "minus_builtin", description = "Subtracts another Duration")
|
||||
@Builtin.Specialize
|
||||
@Builtin.WrapException(from = UnsupportedMessageException.class, to = PanicException.class)
|
||||
@TruffleBoundary
|
||||
public EnsoDuration minus(Object durationObject, InteropLibrary interop)
|
||||
throws UnsupportedMessageException {
|
||||
return new EnsoDuration(duration.minus(interop.asDuration(durationObject)));
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "compare_to_builtin", description = "Compares to other duration")
|
||||
@Builtin.Specialize
|
||||
@Builtin.WrapException(from = UnsupportedMessageException.class, to = PanicException.class)
|
||||
public long compareTo(Object durationObject, InteropLibrary interop)
|
||||
throws UnsupportedMessageException {
|
||||
return duration.compareTo(interop.asDuration(durationObject));
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "equals_builtin")
|
||||
@Builtin.Specialize
|
||||
@Builtin.WrapException(from = UnsupportedMessageException.class, to = PanicException.class)
|
||||
public boolean equalsDuration(Object durationObject, InteropLibrary interop)
|
||||
throws UnsupportedMessageException {
|
||||
return duration.equals(interop.asDuration(durationObject));
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
public boolean isDuration() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
public Duration asDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
@TruffleBoundary
|
||||
public String toDisplayString(boolean allowSideEffects) {
|
||||
return duration.toString();
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ import java.util.Set;
|
||||
*/
|
||||
@ExportLibrary(TypesLibrary.class)
|
||||
@Builtin(pkg = "io", name = "File", stdlibName = "Standard.Base.System.File.File")
|
||||
public class EnsoFile implements TruffleObject {
|
||||
public final class EnsoFile implements TruffleObject {
|
||||
private final TruffleFile truffleFile;
|
||||
|
||||
public EnsoFile(TruffleFile truffleFile) {
|
||||
|
@ -1,28 +1,29 @@
|
||||
package org.enso.interpreter.runtime.data;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives;
|
||||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||
import com.oracle.truffle.api.interop.TruffleObject;
|
||||
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
||||
import com.oracle.truffle.api.library.CachedLibrary;
|
||||
import com.oracle.truffle.api.library.ExportLibrary;
|
||||
import com.oracle.truffle.api.library.ExportMessage;
|
||||
import org.enso.interpreter.dsl.Builtin;
|
||||
import org.enso.interpreter.node.expression.builtin.error.PolyglotError;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.data.text.Text;
|
||||
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||
|
||||
import java.time.DateTimeException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import org.enso.interpreter.dsl.Builtin;
|
||||
import org.enso.interpreter.node.expression.builtin.error.PolyglotError;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.data.text.Text;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
@ExportLibrary(TypesLibrary.class)
|
||||
@Builtin(pkg = "date", name = "TimeOfDay", stdlibName = "Standard.Base.Data.Time.Time_Of_Day")
|
||||
public class EnsoTimeOfDay implements TruffleObject {
|
||||
public final class EnsoTimeOfDay implements TruffleObject {
|
||||
private LocalTime localTime;
|
||||
|
||||
public EnsoTimeOfDay(LocalTime localTime) {
|
||||
@ -77,6 +78,28 @@ public class EnsoTimeOfDay implements TruffleObject {
|
||||
return localTime.getNano();
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "plus_builtin", description = "Adds a duration to this Time_Of_Day")
|
||||
@Builtin.Specialize
|
||||
@Builtin.WrapException(from = UnsupportedMessageException.class, to = PanicException.class)
|
||||
@TruffleBoundary
|
||||
public EnsoTimeOfDay plus(Object durationObject, InteropLibrary interop)
|
||||
throws UnsupportedMessageException {
|
||||
assert interop.isDuration(durationObject);
|
||||
return new EnsoTimeOfDay(localTime.plus(interop.asDuration(durationObject)));
|
||||
}
|
||||
|
||||
@Builtin.Method(
|
||||
name = "minus_builtin",
|
||||
description = "Subtracts a duration from this Time_Of_Day")
|
||||
@Builtin.Specialize
|
||||
@Builtin.WrapException(from = UnsupportedMessageException.class, to = PanicException.class)
|
||||
@TruffleBoundary
|
||||
public EnsoTimeOfDay minus(Object durationObject, InteropLibrary interop)
|
||||
throws UnsupportedMessageException {
|
||||
assert interop.isDuration(durationObject);
|
||||
return new EnsoTimeOfDay(localTime.minus(interop.asDuration(durationObject)));
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Gets a value second")
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public long toSeconds() {
|
||||
|
@ -14,7 +14,7 @@ import java.lang.ref.PhantomReference;
|
||||
/** A runtime representation of a managed resource. */
|
||||
@ExportLibrary(TypesLibrary.class)
|
||||
@Builtin(pkg = "resource", stdlibName = "Standard.Base.Runtime.Resource.Managed_Resource")
|
||||
public class ManagedResource implements TruffleObject {
|
||||
public final class ManagedResource implements TruffleObject {
|
||||
private final Object resource;
|
||||
private PhantomReference<ManagedResource> phantomReference;
|
||||
|
||||
|
@ -11,7 +11,7 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||
/** A mutable reference type. */
|
||||
@ExportLibrary(TypesLibrary.class)
|
||||
@Builtin(pkg = "mutable", stdlibName = "Standard.Base.Runtime.Ref.Ref")
|
||||
public class Ref implements TruffleObject {
|
||||
public final class Ref implements TruffleObject {
|
||||
private volatile Object value;
|
||||
|
||||
/**
|
||||
|
@ -29,7 +29,7 @@ import java.util.*;
|
||||
|
||||
@ExportLibrary(TypesLibrary.class)
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
public class Type implements TruffleObject {
|
||||
public final class Type implements TruffleObject {
|
||||
private final String name;
|
||||
private @CompilerDirectives.CompilationFinal ModuleScope definitionScope;
|
||||
private final boolean builtin;
|
||||
|
@ -18,7 +18,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
/** The main runtime type for Enso's Text. */
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
@ExportLibrary(TypesLibrary.class)
|
||||
public class Text implements TruffleObject {
|
||||
public final class Text implements TruffleObject {
|
||||
private volatile Object contents;
|
||||
private volatile boolean isFlat;
|
||||
private static final Lock lock = new ReentrantLock();
|
||||
|
@ -23,7 +23,7 @@ import java.util.Comparator;
|
||||
|
||||
@Builtin(pkg = "error", stdlibName = "Standard.Base.Warning.Warning")
|
||||
@ExportLibrary(TypesLibrary.class)
|
||||
public class Warning implements TruffleObject {
|
||||
public final class Warning implements TruffleObject {
|
||||
private final Object value;
|
||||
private final Object origin;
|
||||
private final ArrayRope<Reassignment> reassignments;
|
||||
@ -137,7 +137,7 @@ public class Warning implements TruffleObject {
|
||||
}
|
||||
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
public static class Reassignment implements TruffleObject {
|
||||
public static final class Reassignment implements TruffleObject {
|
||||
private final String methodName;
|
||||
private final SourceSection location;
|
||||
|
||||
|
@ -8,7 +8,7 @@ import org.enso.interpreter.runtime.data.ArrayRope;
|
||||
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||
|
||||
@ExportLibrary(TypesLibrary.class)
|
||||
public class WithWarnings implements TruffleObject {
|
||||
public final class WithWarnings implements TruffleObject {
|
||||
private final ArrayRope<Warning> warnings;
|
||||
private final Object value;
|
||||
|
||||
|
@ -17,7 +17,7 @@ import java.math.BigInteger;
|
||||
/** Internal wrapper for a {@link BigInteger}. */
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
@ExportLibrary(TypesLibrary.class)
|
||||
public class EnsoBigInteger implements TruffleObject {
|
||||
public final class EnsoBigInteger implements TruffleObject {
|
||||
private final BigInteger value;
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,7 @@ import org.enso.interpreter.runtime.error.RedefinedMethodException;
|
||||
import org.enso.interpreter.runtime.error.RedefinedConversionException;
|
||||
|
||||
/** A representation of Enso's per-file top-level scope. */
|
||||
public class ModuleScope implements TruffleObject {
|
||||
public final class ModuleScope implements TruffleObject {
|
||||
private final Type associatedType;
|
||||
private final Module module;
|
||||
private Map<String, Object> polyglotSymbols = new HashMap<>();
|
||||
|
@ -28,7 +28,7 @@ import org.enso.polyglot.MethodNames;
|
||||
|
||||
/** Represents the top scope of Enso execution, containing all the importable modules. */
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
public class TopLevelScope implements TruffleObject {
|
||||
public final class TopLevelScope implements TruffleObject {
|
||||
private final Builtins builtins;
|
||||
private final PackageRepository packageRepository;
|
||||
|
||||
|
@ -52,6 +52,7 @@ import org.enso.polyglot.data.TypeGraph;
|
||||
EnsoDateTime.class,
|
||||
EnsoTimeOfDay.class,
|
||||
EnsoTimeZone.class,
|
||||
EnsoDuration.class
|
||||
})
|
||||
public class Types {
|
||||
|
||||
@ -142,6 +143,8 @@ public class Types {
|
||||
return ConstantsGen.DATE_TIME;
|
||||
} else if (TypesGen.isEnsoTimeOfDay(value)) {
|
||||
return ConstantsGen.TIME_OF_DAY;
|
||||
} else if (TypesGen.isEnsoDuration(value)) {
|
||||
return ConstantsGen.DURATION;
|
||||
} else if (TypesGen.isEnsoTimeZone(value)) {
|
||||
return ConstantsGen.TIME_ZONE;
|
||||
} else if (TypesGen.isEnsoFile(value)) {
|
||||
@ -245,6 +248,7 @@ public class Types {
|
||||
graph.insert(ConstantsGen.DATE, ConstantsGen.ANY);
|
||||
graph.insert(ConstantsGen.DATE_TIME, ConstantsGen.ANY);
|
||||
graph.insert(ConstantsGen.TIME_OF_DAY, ConstantsGen.ANY);
|
||||
graph.insert(ConstantsGen.DURATION, ConstantsGen.ANY);
|
||||
graph.insert(ConstantsGen.TIME_ZONE, ConstantsGen.ANY);
|
||||
graph.insertWithoutParent(ConstantsGen.PANIC);
|
||||
graph.insertWithoutParent(Constants.THUNK);
|
||||
|
@ -49,6 +49,7 @@ public record TypeWithKind(String baseType, TypeKind kind) {
|
||||
"org.enso.interpreter.runtime.data.EnsoDateTime",
|
||||
"org.enso.interpreter.runtime.data.EnsoTimeOfDay",
|
||||
"org.enso.interpreter.runtime.data.EnsoTimeZone",
|
||||
"org.enso.interpreter.runtime.data.EnsoDuration",
|
||||
"org.enso.interpreter.runtime.data.ManagedResource",
|
||||
"org.enso.interpreter.runtime.data.Ref",
|
||||
"org.enso.interpreter.runtime.data.text.Text",
|
||||
|
@ -1,4 +1,3 @@
|
||||
import LibraryManifestGenerator.BundledLibrary
|
||||
import sbt.Keys._
|
||||
import sbt._
|
||||
import sbt.internal.util.ManagedLogger
|
||||
@ -6,7 +5,6 @@ import sbt.io.IO
|
||||
import sbt.librarymanagement.{ConfigurationFilter, DependencyFilter}
|
||||
|
||||
import java.io.File
|
||||
import scala.sys.process.Process
|
||||
|
||||
object StdBits {
|
||||
|
||||
@ -24,8 +22,7 @@ object StdBits {
|
||||
def copyDependencies(
|
||||
destination: File,
|
||||
baseJarName: Option[String],
|
||||
ignoreScalaLibrary: Boolean,
|
||||
unpackedDeps: Set[String] = Set()
|
||||
ignoreScalaLibrary: Boolean
|
||||
): Def.Initialize[Task[Unit]] =
|
||||
Def.task {
|
||||
val libraryUpdates = (Compile / update).value
|
||||
@ -53,7 +50,7 @@ object StdBits {
|
||||
report =>
|
||||
val expectedFileNames =
|
||||
report.checked.map(
|
||||
getDestinationFileName(_, unpackedDeps)
|
||||
file => file.getName
|
||||
) ++ baseJarName.toSeq
|
||||
for (existing <- IO.listFiles(destination)) {
|
||||
if (!expectedFileNames.contains(existing.getName)) {
|
||||
@ -67,53 +64,25 @@ object StdBits {
|
||||
log.info(
|
||||
s"Updating changed std-bits dependency ${changed.getName}."
|
||||
)
|
||||
updateDependency(changed, unpackedDeps, destination, log)
|
||||
updateDependency(changed, destination, log)
|
||||
}
|
||||
for (file <- report.unmodified) {
|
||||
val dest = destination / getDestinationFileName(file, unpackedDeps)
|
||||
val dest = destination / file.getName
|
||||
if (!dest.exists()) {
|
||||
log.info(s"Adding missing std-bits dependency ${file.getName}.")
|
||||
updateDependency(file, unpackedDeps, destination, log)
|
||||
updateDependency(file, destination, log)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private def shouldUnpack(jar: File, unpacked: Set[String]): Boolean = {
|
||||
// Maven stores dependencies like this:
|
||||
// .../repo1.maven.org/maven2/org/apache/xmlbeans/xmlbeans/5.0.1/xmlbeans-5.0.1.jar
|
||||
// therefore, the parent of the parent of the jar file is the directory
|
||||
// named with the un-versioned library name.
|
||||
unpacked.contains(jar.getParentFile.getParentFile.getName)
|
||||
}
|
||||
|
||||
private def updateDependency(
|
||||
jar: File,
|
||||
unpacked: Set[String],
|
||||
destinationDir: File,
|
||||
logger: ManagedLogger
|
||||
): Unit = {
|
||||
val destination = destinationDir / getDestinationFileName(jar, unpacked)
|
||||
if (shouldUnpack(jar, unpacked)) {
|
||||
destination.mkdirs()
|
||||
val exitCode = Process(s"jar xf ${jar.getAbsolutePath}", destination).!
|
||||
if (exitCode != 0) {
|
||||
logger.err(s"Could not unpack a dependency jar: $jar.")
|
||||
throw new RuntimeException(s"Could not unpack a dependency jar: $jar.")
|
||||
}
|
||||
} else {
|
||||
IO.copyFile(jar, destination)
|
||||
}
|
||||
}
|
||||
|
||||
private def getDestinationFileName(
|
||||
file: File,
|
||||
unpacked: Set[String]
|
||||
): String = {
|
||||
if (shouldUnpack(file, unpacked)) {
|
||||
val name = file.getName
|
||||
name.stripSuffix(".jar")
|
||||
} else file.getName
|
||||
val destination = destinationDir / jar.getName
|
||||
IO.copyFile(jar, destination)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,10 +6,21 @@ import org.enso.base.time.TimeUtilsBase;
|
||||
import org.enso.base.time.Time_Of_Day_Utils;
|
||||
import org.graalvm.polyglot.Value;
|
||||
|
||||
import java.time.*;
|
||||
import java.time.DateTimeException;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.Period;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.temporal.*;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.time.temporal.TemporalField;
|
||||
import java.time.temporal.WeekFields;
|
||||
import java.util.Locale;
|
||||
|
||||
/** Utils for standard library operations on Time. */
|
||||
@ -79,29 +90,6 @@ public class Time_Utils {
|
||||
}
|
||||
}
|
||||
|
||||
public static ZonedDateTime datetime_adjust(
|
||||
ZonedDateTime datetime, AdjustOp op, Period period, Duration duration) {
|
||||
switch (op) {
|
||||
case PLUS:
|
||||
return datetime.plus(period).plus(duration);
|
||||
case MINUS:
|
||||
return datetime.minus(period).minus(duration);
|
||||
default:
|
||||
throw new DateTimeException("Unknown adjust operation");
|
||||
}
|
||||
}
|
||||
|
||||
public static LocalTime time_adjust(LocalTime time, AdjustOp op, Duration duration) {
|
||||
switch (op) {
|
||||
case PLUS:
|
||||
return time.plus(duration);
|
||||
case MINUS:
|
||||
return time.minus(duration);
|
||||
default:
|
||||
throw new DateTimeException("Unknown adjust operation");
|
||||
}
|
||||
}
|
||||
|
||||
public static int get_field_as_localdate(LocalDate date, TemporalField field) {
|
||||
return date.get(field);
|
||||
}
|
||||
|
@ -92,33 +92,33 @@ spec_with name create_new_date parse_date =
|
||||
date.to_json.should_equal <|
|
||||
Json.from_pairs [["type", "Date"], ["day", date.day], ["month", date.month], ["year", date.year]]
|
||||
|
||||
Test.specify "should add date-based interval" <|
|
||||
Test.specify "should add date-based interval" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
date = create_new_date 1970 + 1.day
|
||||
date . year . should_equal 1970
|
||||
date . month . should_equal 1
|
||||
date . day . should_equal 2
|
||||
|
||||
Test.specify "should subtract date-based interval" <|
|
||||
Test.specify "should subtract date-based interval" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
date = create_new_date 1970 - 1.year
|
||||
date . year . should_equal 1969
|
||||
date . month . should_equal 1
|
||||
date . day . should_equal 1
|
||||
|
||||
Test.specify "should support mixed interval operators" <|
|
||||
Test.specify "should support mixed interval operators" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
date = create_new_date 1970 + 1.month - 1.year
|
||||
date . year . should_equal 1969
|
||||
date . month . should_equal 2
|
||||
date . day . should_equal 1
|
||||
|
||||
Test.specify "should throw error when adding time-based interval" <|
|
||||
case (create_new_date 1970 + 1.hour) . catch of
|
||||
Test.specify "should throw error when adding time-based interval" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
case (create_new_date 1970 + (Duration.new hours=1)) . catch of
|
||||
Time_Error_Data message ->
|
||||
message . should_equal "Date does not support time intervals"
|
||||
result ->
|
||||
Test.fail ("Unexpected result: " + result.to_text)
|
||||
|
||||
Test.specify "should throw error when subtracting time-based interval" <|
|
||||
case (create_new_date 1970 - (1.day - 1.minute)) . catch of
|
||||
Test.specify "should throw error when subtracting time-based interval" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
case (create_new_date 1970 - (1.day - (Duration.new minutes=1))) . catch of
|
||||
Time_Error_Data message ->
|
||||
message . should_equal "Date does not support time intervals"
|
||||
result ->
|
||||
@ -199,7 +199,7 @@ spec_with name create_new_date parse_date =
|
||||
(create_new_date 2000 7 1).end_of Date_Period.Quarter . should_equal (Date.new 2000 9 30)
|
||||
(create_new_date 2000 6 30).end_of Date_Period.Quarter . should_equal (Date.new 2000 6 30)
|
||||
|
||||
Test.specify "should allow to compute the number of working days until a later date" <|
|
||||
Test.specify "should allow to compute the number of working days until a later date" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
# 2000-2-1 is a Tuesday
|
||||
create_new_date 2000 2 1 . work_days_until (create_new_date 2000 2 1) . should_equal 0
|
||||
create_new_date 2000 2 1 . work_days_until (create_new_date 2000 2 2) . should_equal 1
|
||||
@ -250,7 +250,7 @@ spec_with name create_new_date parse_date =
|
||||
# We duplicate the holiday entries to check that the functions are resilient to such input data.
|
||||
duplicated_holiday_november year =
|
||||
holiday_november year + holiday_november year + holiday_november year
|
||||
Test.specify "should allow to compute the number of working days until a date, skipping custom set holidays" <|
|
||||
Test.specify "should allow to compute the number of working days until a date, skipping custom set holidays" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
holiday_february = Vector.new 29 (i -> create_new_date 2000 2 i+1)
|
||||
create_new_date 2000 2 1 . work_days_until (create_new_date 2000 3 1) holiday_february . should_equal 0
|
||||
create_new_date 2000 2 10 . work_days_until (create_new_date 2000 2 12) holiday_february . should_equal 0
|
||||
@ -265,7 +265,7 @@ spec_with name create_new_date parse_date =
|
||||
create_new_date 2000 11 1 . work_days_until (create_new_date 2000 12 1) (duplicated_holiday_november 2020) . should_equal 22
|
||||
create_new_date 1999 11 1 . work_days_until (create_new_date 1999 12 1) (duplicated_holiday_november 1999) . should_equal 19
|
||||
|
||||
Test.specify "should allow to compute the number of working days including the end, in a manner consistent with NETWORKDAYS" <|
|
||||
Test.specify "should allow to compute the number of working days including the end, in a manner consistent with NETWORKDAYS" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
create_new_date 2000 2 1 . work_days_until (create_new_date 2000 2 1) include_end_date=True . should_equal 1
|
||||
create_new_date 2000 2 1 . work_days_until (create_new_date 2000 2 2) include_end_date=True . should_equal 2
|
||||
create_new_date 2000 2 3 . work_days_until (create_new_date 2000 2 16) include_end_date=True . should_equal 10
|
||||
@ -282,7 +282,7 @@ spec_with name create_new_date parse_date =
|
||||
create_new_date 2000 2 6 . work_days_until (create_new_date 2000 2 8) include_end_date=True . should_equal 2
|
||||
create_new_date 2000 2 6 . work_days_until (create_new_date 2000 2 5) include_end_date=True . should_equal 0
|
||||
|
||||
Test.specify "should allow to shift the date by N working days" <|
|
||||
Test.specify "should allow to shift the date by N working days" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
# 2000-2-1 is a Tuesday
|
||||
create_new_date 2000 2 1 . add_work_days 0 . should_equal (Date.new 2000 2 1)
|
||||
create_new_date 2000 2 1 . add_work_days . should_equal (Date.new 2000 2 2)
|
||||
@ -314,7 +314,7 @@ spec_with name create_new_date parse_date =
|
||||
create_new_date 2022 3 27 . add_work_days 0 . should_equal (Date.new 2022 3 28)
|
||||
create_new_date 2022 3 27 . add_work_days 1 . should_equal (Date.new 2022 3 29)
|
||||
|
||||
Test.specify "should allow to shift the date by negative amount of working days" <|
|
||||
Test.specify "should allow to shift the date by negative amount of working days" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
# 2000-2-1 is a Tuesday
|
||||
create_new_date 2000 2 1 . add_work_days -1 . should_equal (Date.new 2000 1 31)
|
||||
create_new_date 2000 2 1 . add_work_days -2 . should_equal (Date.new 2000 1 28)
|
||||
@ -343,7 +343,7 @@ spec_with name create_new_date parse_date =
|
||||
create_new_date 2000 2 6 . add_work_days -5 . should_equal (Date.new 2000 1 31)
|
||||
create_new_date 2000 2 6 . add_work_days -6 . should_equal (Date.new 2000 1 28)
|
||||
|
||||
Test.specify "should allow to shift the date by N working days, skipping custom holidays" <|
|
||||
Test.specify "should allow to shift the date by N working days, skipping custom holidays" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
all_year_holiday year =
|
||||
first_day = create_new_date year 1 1
|
||||
Vector.new first_day.length_of_year (n -> first_day + n.days)
|
||||
@ -364,7 +364,7 @@ spec_with name create_new_date parse_date =
|
||||
create_new_date 1999 10 30 . add_work_days 0 (duplicated_holiday_november 1999) . should_equal (Date.new 1999 11 3)
|
||||
create_new_date 1999 10 30 . add_work_days 1 (duplicated_holiday_november 1999) . should_equal (Date.new 1999 11 4)
|
||||
|
||||
Test.specify "add_work_days and work_days_until should be consistent with each other" <|
|
||||
Test.specify "add_work_days and work_days_until should be consistent with each other" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
first_day = create_new_date 2020 1 1
|
||||
dates = Vector.new 100 (n -> first_day + n.days)
|
||||
holidays = [1, 2, 10, 11, 12, 13, 14, 15, 30, 40, 41, 42, 50, 60].map (n -> first_day + n.days)
|
||||
|
@ -230,7 +230,7 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
time . day . should_equal 1
|
||||
|
||||
Test.specify "should add time interval" <|
|
||||
time = create_new_datetime 1970 (zone = Time_Zone.utc) + 1.nanosecond
|
||||
time = create_new_datetime 1970 (zone = Time_Zone.utc) + (Duration.new nanoseconds=1)
|
||||
time . year . should_equal 1970
|
||||
time . month . should_equal 1
|
||||
time . day . should_equal 1
|
||||
@ -240,7 +240,7 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
time . nanosecond . should_equal 1
|
||||
time . zone . should_equal Time_Zone.utc
|
||||
|
||||
Test.specify "should add date interval" <|
|
||||
Test.specify "should add date interval" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
time = create_new_datetime 1970 (zone = Time_Zone.utc) + 1.month
|
||||
time . year . should_equal 1970
|
||||
time . month . should_equal 2
|
||||
@ -251,8 +251,8 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
time . nanosecond . should_equal 0
|
||||
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
|
||||
|
||||
Test.specify "should add mixed date time interval" <|
|
||||
time = create_new_datetime 1970 (zone = Time_Zone.utc) + (1.month + 3.hours)
|
||||
Test.specify "should add mixed date time interval" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
time = create_new_datetime 1970 (zone = Time_Zone.utc) + (1.month + (Duration.new hours=3))
|
||||
time . year . should_equal 1970
|
||||
time . month . should_equal 2
|
||||
time . day . should_equal 1
|
||||
@ -263,7 +263,7 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
|
||||
|
||||
Test.specify "should subtract time interval" <|
|
||||
time = create_new_datetime 1970 (zone = Time_Zone.utc) - 1.hour
|
||||
time = create_new_datetime 1970 (zone = Time_Zone.utc) - (Duration.new hours=1)
|
||||
time . year . should_equal 1969
|
||||
time . month . should_equal 12
|
||||
time . day . should_equal 31
|
||||
@ -273,7 +273,7 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
time . nanosecond . should_equal 0
|
||||
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
|
||||
|
||||
Test.specify "should subtract date interval" <|
|
||||
Test.specify "should subtract date interval" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
time = create_new_datetime 1970 (zone = Time_Zone.utc) - 1.month
|
||||
time . year . should_equal 1969
|
||||
time . month . should_equal 12
|
||||
@ -284,8 +284,8 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
time . nanosecond . should_equal 0
|
||||
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
|
||||
|
||||
Test.specify "should subtract mixed date time interval" <|
|
||||
time = create_new_datetime 1970 (zone = Time_Zone.utc) - (1.month - 3.hours)
|
||||
Test.specify "should subtract mixed date time interval" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
time = create_new_datetime 1970 (zone = Time_Zone.utc) - (1.month - (Duration.new hours=3))
|
||||
time . year . should_equal 1969
|
||||
time . month . should_equal 12
|
||||
time . day . should_equal 1
|
||||
@ -295,8 +295,8 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
time . nanosecond . should_equal 0
|
||||
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
|
||||
|
||||
Test.specify "should support mixed interval operators" <|
|
||||
time = create_new_datetime 1970 (zone = Time_Zone.utc) - 1.month + 12.hours
|
||||
Test.specify "should support mixed interval operators" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
time = create_new_datetime 1970 (zone = Time_Zone.utc) - 1.month + (Duration.new hours=12)
|
||||
time . year . should_equal 1969
|
||||
time . month . should_equal 12
|
||||
time . day . should_equal 1
|
||||
@ -428,7 +428,7 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
Test.specify "should find start/end of a Date_Period or Time_Period containing the current datetime correctly near the spring DST switch" pending=js_dst_pending <|
|
||||
d1 = create_new_datetime 2022 3 27 1 34 15 0 tz
|
||||
d2 = create_new_datetime 2022 3 27 3 34 15 0 tz
|
||||
d1_plus = d1 + 1.hour
|
||||
d1_plus = d1 + (Duration.new hours=1)
|
||||
d1_plus . should_equal d2
|
||||
|
||||
check_dates_spring date =
|
||||
@ -460,7 +460,7 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
dst_overlap_message = "We cannot correctly migrate the datetime inside of the timeline overlap through the polyglot boundar - as due to polyglot conversion limitation, always the earlier one is chosen. See the bug report: https://github.com/oracle/graal/issues/4918"
|
||||
Test.specify "should find start/end of a Date_Period or Time_Period containing the current datetime correctly near the autumn DST switch" pending=dst_overlap_message <|
|
||||
d3 = create_new_datetime 2022 10 30 2 30 15 0 tz
|
||||
d4 = d3 + (1.hour)
|
||||
d4 = d3 + (Duration.new hours=1)
|
||||
|
||||
d3.hour . should_equal 2
|
||||
d4.hour . should_equal 2
|
||||
@ -502,7 +502,7 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
d4_end.nanosecond . should_equal max_nanos
|
||||
Time_Utils.get_datetime_offset d4_end . should_equal offset_1_h
|
||||
|
||||
Test.specify "should allow to shift the date by N working days" <|
|
||||
Test.specify "should allow to shift the date by N working days" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
# 2000-2-1 is a Tuesday
|
||||
create_new_datetime 2000 2 1 12 30 . add_work_days 0 . should_equal (Date_Time.new 2000 2 1 12 30)
|
||||
create_new_datetime 2000 2 1 12 15 55 . add_work_days . should_equal (Date_Time.new 2000 2 2 12 15 55)
|
||||
@ -523,7 +523,7 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
create_new_datetime 2000 2 27 12 10 . add_work_days 3 . should_equal (Date_Time.new 2000 3 2 12 10)
|
||||
create_new_datetime 1999 2 27 12 10 . add_work_days 3 . should_equal (Date_Time.new 1999 3 4 12 10)
|
||||
|
||||
Test.specify "should handle shifting dates around spring DST edge cases" pending=js_dst_pending <|
|
||||
Test.specify "should handle shifting dates around spring DST edge cases" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
# 2022-10-30 and 2022-03-27 are DST switch days, Sundays.
|
||||
create_new_datetime 2022 10 30 2 30 55 1234 . add_work_days 0 . should_equal (Date_Time.new 2022 10 31 2 30 55 1234)
|
||||
create_new_datetime 2022 10 30 1 30 . add_work_days 1 . should_equal (Date_Time.new 2022 11 1 1 30)
|
||||
@ -534,12 +534,12 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
|
||||
Test.specify "should handle shifting dates around autumn DST edge cases" pending=dst_overlap_message <|
|
||||
d3 = create_new_datetime 2022 10 30 2 30 15 0 tz
|
||||
d4 = d3 + (1.hour)
|
||||
d4 = d3 + (Duration.new hours=1)
|
||||
|
||||
# TODO we need to check and document the actual behaviour once it is expressible, it may be equally acceptable to shift to 3:30 instead of 2:30.
|
||||
d4 . add_work_days 0 . should_equal (Date_Time.new 2022 10 31 2 30 15 0 tz)
|
||||
|
||||
Test.specify "should allow to shift the date by negative amount of working days" <|
|
||||
Test.specify "should allow to shift the date by negative amount of working days" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
# 2000-2-1 is a Tuesday
|
||||
create_new_datetime 2000 2 1 12 30 . add_work_days -1 . should_equal (Date_Time.new 2000 1 31 12 30)
|
||||
create_new_datetime 2000 2 1 13 30 . add_work_days -2 . should_equal (Date_Time.new 2000 1 28 13 30)
|
||||
@ -549,7 +549,7 @@ spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=
|
||||
create_new_datetime 2000 2 6 0 1 . add_work_days -2 . should_equal (Date_Time.new 2000 2 3 0 1)
|
||||
create_new_datetime 2000 2 6 23 59 . add_work_days -6 . should_equal (Date_Time.new 2000 1 28 23 59)
|
||||
|
||||
Test.specify "should allow to shift the date by N working days, skipping custom holidays" <|
|
||||
Test.specify "should allow to shift the date by N working days, skipping custom holidays" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
all_year_holiday year =
|
||||
first_day = Date.new year 1 1
|
||||
Vector.new first_day.length_of_year (n -> first_day + n.days)
|
||||
|
@ -3,99 +3,93 @@ from Standard.Base import all
|
||||
import Standard.Base.Data.Time.Duration
|
||||
import Standard.Test
|
||||
|
||||
polyglot java import java.time.Duration as Java_Duration
|
||||
polyglot java import java.time.LocalDate
|
||||
polyglot java import java.time.LocalDateTime as Java_DateTime
|
||||
|
||||
|
||||
java_datetime year month=1 day=1 hour=0 minute=0 second=0 nanosecond=0 =
|
||||
Panic.catch Any (Java_DateTime.of year month day hour minute second nanosecond) (err -> Error.throw (Time_Error_Data <| err.payload.to_display_text.drop (Text_Sub_Range.First 16)))
|
||||
|
||||
js_datetime year month=1 day=1 hour=0 minute=0 second=0 nanosecond=0 =
|
||||
Panic.catch Any (js_datetime_impl year month day hour minute second nanosecond) (err -> Error.throw (Time_Error_Data err.payload.cause))
|
||||
|
||||
foreign js js_datetime_impl year month day hour minute second nanosecond = """
|
||||
if (month > 12 || month < 1) {
|
||||
throw `Invalid value for MonthOfYear (valid values 1 - 12): ${month}`;
|
||||
}
|
||||
return new Date(year, month - 1, day, hour, minute, second, nanosecond / 1000000);
|
||||
|
||||
spec =
|
||||
Test.group "Duration" <|
|
||||
|
||||
Test.specify "should create interval seconds" <|
|
||||
interval = 5.seconds
|
||||
interval.to_vector . should_equal [0, 0, 0, 0, 0, 5, 0]
|
||||
|
||||
Test.specify "should create interval months" <|
|
||||
interval = 9.months
|
||||
interval.to_vector . should_equal [0, 9, 0, 0, 0, 0, 0]
|
||||
|
||||
Test.specify "should add days to nanoseconds" <|
|
||||
interval = 7.nanoseconds + 3.days
|
||||
interval.to_vector . should_equal [0, 0, 3, 0, 0, 0, 7]
|
||||
|
||||
Test.specify "should add milliseconds to years" <|
|
||||
interval = 4.years + 8.milliseconds
|
||||
interval.to_vector . should_equal [4, 0, 0, 0, 0, 0, 8000000]
|
||||
|
||||
Test.specify "should substract seconds from months" <|
|
||||
interval = 8.months - 8.seconds
|
||||
interval.to_vector . should_equal [0, 8, 0, 0, 0, -8, 0]
|
||||
|
||||
Test.specify "should subtract years from hours" <|
|
||||
interval = 2.hours - 11.years
|
||||
interval.to_vector . should_equal [-11, 0, 0, 2, 0, 0, 0]
|
||||
|
||||
Test.specify "should support mixed operators" <|
|
||||
interval = 2.hours + 12.seconds - 11.years
|
||||
interval.to_vector . should_equal [-11, 0, 0, 2, 0, 12, 0]
|
||||
duration = (Duration.new seconds=5)
|
||||
duration.seconds . should_equal 5
|
||||
duration.milliseconds . should_equal 0
|
||||
|
||||
Test.specify "should create interval between two points in time" <|
|
||||
time1 = Date_Time.new 2001 1 2
|
||||
time2 = Date_Time.new 2001 2 1
|
||||
interval = Duration.between time1 time2
|
||||
interval.to_vector . should_equal [0, 0, 0, 720, 0, 0, 0]
|
||||
|
||||
Test.specify "should check if time based" <|
|
||||
interval = 10.hours
|
||||
interval.is_date . should_be_false
|
||||
interval.is_time . should_be_true
|
||||
|
||||
Test.specify "should check if date based" <|
|
||||
interval = 10.years
|
||||
interval.is_date . should_be_true
|
||||
interval.is_time . should_be_false
|
||||
|
||||
Test.specify "should check if mixed based" <|
|
||||
interval = 10.years + 3.hours
|
||||
interval.is_date . should_be_true
|
||||
interval.is_time . should_be_true
|
||||
(Duration.between (Date_Time.new 2001 1 1 3) (Date_Time.new 2001 1 1 10)).total_hours . should_equal 7
|
||||
(Duration.between (Date_Time.new 2001 1 1) (Date_Time.new 2001 1 7)).total_hours . should_equal (6 * 24)
|
||||
(Duration.between (Date_Time.new 2001 1 1 13) (Date_Time.new 2001 1 7 16)).total_hours . should_equal (3 + 6 * 24)
|
||||
|
||||
Test.specify "should check if empty" <|
|
||||
interval = 0.seconds
|
||||
interval = Duration.zero
|
||||
interval.is_empty . should_be_true
|
||||
|
||||
Test.specify "should normalize periods" <|
|
||||
interval = 12.months
|
||||
interval.to_vector . should_equal [1, 0, 0, 0, 0, 0, 0]
|
||||
(Duration.new seconds=60).total_minutes . should_equal 1
|
||||
(Duration.new milliseconds=1000).total_seconds . should_equal 1
|
||||
|
||||
Test.specify "should normalize addition" <|
|
||||
interval = 11.months + 1.month
|
||||
interval.to_vector . should_equal [1, 0, 0, 0, 0, 0, 0]
|
||||
duration = (Duration.new hours=11) + (Duration.new hours=1)
|
||||
duration.hours . should_equal 12
|
||||
|
||||
Test.specify "should normalize subtraction" <|
|
||||
interval = 13.months - 1.month
|
||||
interval.to_vector . should_equal [1, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
Test.specify "should check equality" <|
|
||||
3.seconds.should_equal 3.seconds
|
||||
60.seconds.should_equal 1.minute
|
||||
61.seconds.should_equal (1.minute + 1.second)
|
||||
60.minutes.should_equal 1.hour
|
||||
(24.hours == 1.day) . should_be_false
|
||||
(30.days == 1.month) . should_be_false
|
||||
12.months.should_equal 1.year
|
||||
18.months.should_equal (1.year + 6.months)
|
||||
1.year.should_equal (11.months + 1.month)
|
||||
10.years.should_equal 10.years
|
||||
duration = (Duration.new hours=13) - (Duration.new hours=1)
|
||||
duration.hours . should_equal 12
|
||||
|
||||
Test.specify "should convert to Json" <|
|
||||
interval = 120.nanoseconds + 30.seconds + 14.hours + 12.days + 1.month + 9.years
|
||||
interval = (Duration.new nanoseconds=120) + (Duration.new seconds=30) + (Duration.new hours=14)
|
||||
interval.to_json.should_equal <|
|
||||
duration_pairs = [["nanoseconds", interval.nanoseconds], ["seconds", interval.seconds], ["hours", interval.hours], ["days", interval.days], ["months", interval.months], ["years", interval.years]]
|
||||
duration_pairs = [["nanoseconds", interval.nanoseconds], ["seconds", interval.seconds], ["hours", interval.hours]]
|
||||
Json.from_pairs ([["type", "Duration"]] + duration_pairs)
|
||||
|
||||
Test.specify "should be comparable" <|
|
||||
duration_1 = 1.year
|
||||
duration_2 = 24.days
|
||||
duration_1 = (Duration.new hours=5)
|
||||
duration_2 = (Duration.new minutes=1)
|
||||
duration_1.compare_to duration_1 . should_equal Ordering.Equal
|
||||
duration_1==duration_1 . should_be_true
|
||||
duration_1!=duration_2 . should_be_true
|
||||
duration_1>duration_2 . should_be_true
|
||||
duration_1<duration_2 . should_be_false
|
||||
|
||||
Test.specify "Date_Time supports adding and subtracting Duration" <|
|
||||
((Date_Time.new 2022 10 1 hour=10) + (Duration.new hours=2)) . should_equal (Date_Time.new 2022 10 1 hour=12)
|
||||
((Date_Time.new 2022 10 1 hour=10) - (Duration.new hours=2)) . should_equal (Date_Time.new 2022 10 1 hour=8)
|
||||
((Date_Time.new 2022 10 2) - (Duration.new hours=24)) . should_equal (Date_Time.new 2022 10 1)
|
||||
((Date_Time.new 2022 10 1 hour=2) - (Duration.new minutes=3)) . should_equal (Date_Time.new 2022 10 1 hour=1 minute=57)
|
||||
|
||||
Test.specify "Java Duration is equal to Enso Duration" <|
|
||||
(Duration.new hours=1) . should_equal (Java_Duration.ofHours 1)
|
||||
(Duration.new minutes=80) . should_equal (Java_Duration.ofMinutes 80)
|
||||
(Java_Duration.ofSeconds 30) . should_equal (Duration.new seconds=30)
|
||||
|
||||
Test.specify "Difference of Java Date and Enso date should be an Enso Duration" <|
|
||||
(Duration.between (java_datetime 2022 01 01) (Date_Time.new 2022 01 02) timezone_aware=False).total_hours . should_equal 24
|
||||
(Duration.between (Date_Time.new 2022 01 01) (java_datetime 2022 01 02) timezone_aware=False).total_hours . should_equal 24
|
||||
(Duration.between (Date_Time.new 2022 01 01 13) (java_datetime 2022 01 01 14) timezone_aware=False).total_hours . should_equal 1
|
||||
(Duration.between (java_datetime 2022 01 01 13 13) (Date_Time.new 2022 01 01 13 15) timezone_aware=False).total_minutes . should_equal 2
|
||||
|
||||
Test.specify "Difference of two Java Dates should be an Enso Duration" <|
|
||||
(Duration.between (java_datetime 2022 01 01) (java_datetime 2022 01 02) timezone_aware=False).total_hours . should_equal 24
|
||||
|
||||
Test.specify "Difference of two JS Dates is an Enso Duration" <|
|
||||
(Duration.between (js_datetime 2022 09 01) (js_datetime 2022 09 02) timezone_aware=False).total_hours . should_equal 24
|
||||
|
||||
Test.specify "Difference of JS Dates and Java Dates should be Enso Duration" <|
|
||||
(Duration.between (js_datetime 2022 09 08) (java_datetime 2022 09 09) timezone_aware=False).total_hours . should_equal 24
|
||||
(Duration.between (java_datetime 2022 09 09) (js_datetime 2022 09 08) timezone_aware=False).total_hours . should_equal (-24)
|
||||
|
||||
|
||||
main = Test.Suite.run_main spec
|
||||
|
@ -83,26 +83,26 @@ specWith name create_new_time parse_time =
|
||||
datetime . zone . zone_id . should_equal Time_Zone.utc.zone_id
|
||||
|
||||
Test.specify "should add time-based interval" <|
|
||||
time = create_new_time 0 + 1.minute
|
||||
time = create_new_time 0 + (Duration.new minutes=1)
|
||||
time . to_seconds . should_equal 60
|
||||
|
||||
Test.specify "should subtract time-based interval" <|
|
||||
time = create_new_time 0 - 1.minute
|
||||
time = create_new_time 0 - (Duration.new minutes=1)
|
||||
time . to_seconds . should_equal 86340
|
||||
|
||||
Test.specify "should support mixed interval operators" <|
|
||||
time = create_new_time 0 + 1.hour - 1.second
|
||||
time = create_new_time 0 + (Duration.new hours=1) - (Duration.new seconds=1)
|
||||
time . to_seconds . should_equal 3599
|
||||
|
||||
Test.specify "should throw error when adding date-based interval" <|
|
||||
Test.specify "should throw error when adding date-based interval" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
case (create_new_time 0 + 1.day) . catch of
|
||||
Time_Error_Data message ->
|
||||
message . should_equal "Time_Of_Day does not support date intervals"
|
||||
result ->
|
||||
Test.fail ("Unexpected result: " + result.to_text)
|
||||
|
||||
Test.specify "should throw error when subtracting date-based interval" <|
|
||||
case (create_new_time 0 - (1.day - 1.minute)) . catch of
|
||||
Test.specify "should throw error when subtracting date-based interval" pending="Wait until Period type is implemented (https://www.pivotaltracker.com/story/show/183336003)" <|
|
||||
case (create_new_time 0 - (1.day - (Duration.new minutes=1))) . catch of
|
||||
Time_Error_Data message ->
|
||||
message . should_equal "Time_Of_Day does not support date intervals"
|
||||
result ->
|
||||
|
@ -30,8 +30,8 @@ spec =
|
||||
url_get = base_url_with_slash + "get"
|
||||
url_post = base_url_with_slash + "post"
|
||||
Test.specify "should create HTTP client with timeout setting" <|
|
||||
http = Http.new (timeout = 30.seconds)
|
||||
http.timeout.should_equal 30.seconds
|
||||
http = Http.new (timeout = (Duration.new seconds=30))
|
||||
http.timeout.should_equal (Duration.new seconds=30)
|
||||
Test.specify "should create HTTP client with follow_redirects setting" <|
|
||||
http = Http.new (follow_redirects = False)
|
||||
http.follow_redirects.should_equal False
|
||||
|
@ -1,4 +1,5 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Test
|
||||
|
||||
polyglot java import java.lang.Float
|
||||
polyglot java import java.lang.Integer
|
||||
@ -9,7 +10,6 @@ polyglot java import java.util.ArrayList
|
||||
polyglot java import java.time.LocalDate
|
||||
polyglot java import java.time.LocalTime
|
||||
|
||||
import Standard.Test
|
||||
|
||||
Any.test_me x = x.is_nothing
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user