mirror of
https://github.com/enso-org/enso.git
synced 2024-11-30 04:12:18 +03:00
Don't add module's builtins to the scope of a builtin type (#3791)
It appears that we were always adding builtin methods to the scope of the module and the builtin type that shared the same name. This resulted in some methods being accidentally available even though they shouldn't. This change treats differently builtins of types and modules and introduces auto-registration feature for builtins. By default all builtin methods are registered with a type, unless explicitly defined in the annotation property. Builtin methods that are auto-registered do not have to be explicitly defined and are registered with the underlying type. Registration correctly infers the right type, depending whether we deal with static or instance methods. Builtin methods that are not auto-registered have to be explicitly defined **always**. Modules' builtin methods are the prime example. # Important Notes Builtins now carry information whether they are static or not (inferred from the lack of `self` parameter). They also carry a `autoRegister` property to determine if a builtin method should be automatically registered with the type.
This commit is contained in:
parent
88e40479d1
commit
7b0759f8b3
@ -431,6 +431,7 @@
|
||||
- [Distinguish static and instance methods][3740]
|
||||
- [By-type pattern matching][3742]
|
||||
- [Fix performance of method calls on polyglot arrays][3781]
|
||||
- [Improved support for static and non-static builtins][3791]
|
||||
- [Missing foreign language generates proper Enso error][3798]
|
||||
- [Made Vector performance to be on par with Array][3811]
|
||||
- [Introduced IO Permission Contexts][3828]
|
||||
@ -494,6 +495,7 @@
|
||||
[3764]: https://github.com/enso-org/enso/pull/3764
|
||||
[3742]: https://github.com/enso-org/enso/pull/3742
|
||||
[3781]: https://github.com/enso-org/enso/pull/3781
|
||||
[3791]: https://github.com/enso-org/enso/pull/3791
|
||||
[3798]: https://github.com/enso-org/enso/pull/3798
|
||||
[3811]: https://github.com/enso-org/enso/pull/3811
|
||||
[3828]: https://github.com/enso-org/enso/pull/3828
|
||||
|
@ -17,7 +17,7 @@ type Any
|
||||
Arguments:
|
||||
- handler: The function to call on this if it is an error value.
|
||||
catch_primitive : (Error -> Any) -> Any
|
||||
catch_primitive handler = @Builtin_Method "Any.catch_primitive"
|
||||
catch_primitive self handler = @Builtin_Method "Any.catch_primitive"
|
||||
|
||||
## Generic conversion of an arbitrary Enso value to a corresponding textual
|
||||
representation.
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
from Standard.Base import all
|
||||
|
||||
import Standard.Base.Data.Array
|
||||
import Standard.Base.Data.Text.Regex
|
||||
|
||||
import Standard.Base.Data.Text.Matching_Mode
|
||||
|
@ -36,6 +36,7 @@ today = now
|
||||
## Constructs a new Date from a year, month, and day.
|
||||
|
||||
Arguments
|
||||
- year: The year to represent.
|
||||
- month: The month-of-year to represent, from 1 (January) to 12 (December).
|
||||
- day: The day-of-month to represent, from 1 to 31. It must be valid for the
|
||||
year and month.
|
||||
@ -63,10 +64,23 @@ new year (month = 1) (day = 1) =
|
||||
instead of Enso format. Hopefully this will be fixed with
|
||||
https://github.com/enso-org/enso/pull/3559
|
||||
Then this should be switched to use `Panic.catch_java`.
|
||||
Panic.recover Any (Date.internal_new year month day) . catch Any e-> case e of
|
||||
Panic.recover Any (new_builtin year month day) . catch Any e-> case e of
|
||||
Polyglot_Error_Data err -> Error.throw (Time_Error_Data err.getMessage)
|
||||
ex -> ex
|
||||
|
||||
## PRIVATE
|
||||
Constructs a new Date from a year, month, and day.
|
||||
|
||||
Arguments
|
||||
- year: The year to represent.
|
||||
- month: The month-of-year to represent, from 1 (January) to 12 (December).
|
||||
- day: The day-of-month to represent, from 1 to 31. It must be valid for the
|
||||
year and month.
|
||||
|
||||
Recommended to use `Date.new` instead which handles potential exceptions.
|
||||
new_builtin : Integer -> Integer -> Integer -> Date
|
||||
new_builtin year month day = @Builtin_Method "Date.new_builtin"
|
||||
|
||||
## ALIAS Date from Text
|
||||
|
||||
Converts text containing a date into a Date object.
|
||||
@ -132,13 +146,42 @@ new year (month = 1) (day = 1) =
|
||||
parse : Text -> (Text | Nothing) -> Date ! Time_Error
|
||||
parse text pattern=Nothing =
|
||||
result = Panic.recover Any <| case pattern of
|
||||
Nothing -> Date.internal_parse text 0
|
||||
_ : Text -> Date.internal_parse text pattern
|
||||
Nothing -> parse_builtin text 0
|
||||
_ : Text -> parse_builtin text pattern
|
||||
_ -> Panic.throw (Time_Error_Data "An invalid pattern was provided.")
|
||||
result . map_error <| case _ of
|
||||
Polyglot_Error_Data err -> Time_Error_Data err.getMessage
|
||||
ex -> ex
|
||||
|
||||
## PRIVATE
|
||||
Converts text containing a date into a Date object.
|
||||
|
||||
Arguments:
|
||||
- text: The text to try and parse as a date.
|
||||
- pattern: An optional pattern describing how to parse the text.
|
||||
|
||||
Recommended to use `Date.parse` instead which handles potential exceptions.
|
||||
|
||||
? Pattern Syntax
|
||||
Patterns are based on a simple sequence of letters and symbols. For
|
||||
example, "d MMM yyyy" will format "2011-12-03" as "3 Dec 2011".
|
||||
|
||||
? Default Date Formatting
|
||||
Unless you provide a custom format, the text must represent a valid date
|
||||
that can be parsed using the ISO-8601 extended local date format. The
|
||||
format consists of:
|
||||
|
||||
- Four digits or more for the year. Years in the range 0000 to 9999
|
||||
will be pre-padded by zero to ensure four digits. Years outside
|
||||
that range will have a prefixed positive or negative symbol.
|
||||
- A dash
|
||||
- Two digits for the month-of-year. This is pre-padded by zero to ensure
|
||||
two digits.
|
||||
- A dash
|
||||
- Two digits for the day-of-month. This is pre-padded by zero to ensure two
|
||||
digits.
|
||||
parse_builtin : Text -> Any -> Date
|
||||
parse_builtin text pattern = @Builtin_Method "Date.parse_builtin"
|
||||
|
||||
## This type represents a date, often viewed as year-month-day.
|
||||
|
||||
@ -484,7 +527,6 @@ type Date
|
||||
_ ->
|
||||
Error.throw (Illegal_Argument_Error_Data "Illegal period argument")
|
||||
|
||||
|
||||
## A Date to Json conversion.
|
||||
|
||||
> Example
|
||||
|
@ -86,9 +86,29 @@ now = @Builtin_Method "Date_Time.now"
|
||||
example_new = Date_Time.new 1986 8 5
|
||||
new : Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Time_Zone -> Date_Time ! Time_Error
|
||||
new year (month = 1) (day = 1) (hour = 0) (minute = 0) (second = 0) (nanosecond = 0) (zone = Time_Zone.system) =
|
||||
Panic.catch_java Any (Date_Time.new_builtin year month day hour minute second nanosecond zone) java_exception->
|
||||
Panic.catch_java Any (new_builtin year month day hour minute second nanosecond zone) java_exception->
|
||||
Error.throw (Time_Error_Data java_exception.getMessage)
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Obtains an instance of `Date_Time` from a year, month, day, hour, minute,
|
||||
second, nanosecond and timezone.
|
||||
|
||||
Arguments:
|
||||
- year: The year to represent, any Integer is valid.
|
||||
- month: the month-of-year to represent, from 1 (January) to 12 (December)
|
||||
- day: the day-of-month to represent, from 1 to 31 and must be valid for the
|
||||
year and month
|
||||
- hour: the hour-of-day to represent, from 0 to 23
|
||||
- minute: the minute-of-hour to represent, from 0 to 59
|
||||
- second: the second-of-minute to represent, from 0 to 59
|
||||
- nanosecond: the nano-of-second to represent, from 0 to 999,999,999
|
||||
- zone: the timezone
|
||||
|
||||
Recommended to use `Date_Time.new` instead which handles potential exceptions.
|
||||
new_builtin : Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Time_Zone -> Date_Time
|
||||
new_builtin year month day hour minute second nanosecond zone = @Builtin_Method "Date_Time.new_builtin"
|
||||
|
||||
## ALIAS Time from Text
|
||||
|
||||
Obtains an instance of `Time` from a text such as
|
||||
@ -171,9 +191,21 @@ parse : Text -> Text | Nothing -> Locale -> Date_Time ! Time_Error
|
||||
parse text pattern=Nothing locale=Locale.default =
|
||||
Panic.catch_java Any handler=(java_exception -> Error.throw (Time_Error_Data java_exception.getMessage)) <|
|
||||
case pattern of
|
||||
Nothing -> Date_Time.parse_builtin text
|
||||
Nothing -> parse_builtin text
|
||||
_ : Text -> Time_Utils.parse_datetime_format text pattern locale.java_locale
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Obtains an instance of `Time` from a text such as
|
||||
"2007-12-03T10:15:30+01:00 Europe/Paris".
|
||||
|
||||
Arguments:
|
||||
- text: The text representing the time to be parsed.
|
||||
|
||||
Recommended to use `Date_Time.parse_builtin` instead which handles potential exceptions
|
||||
and date time formats.
|
||||
parse_builtin : Text -> Date_Time
|
||||
parse_builtin text = @Builtin_Method "Date_Time.parse_builtin"
|
||||
|
||||
## PRIVATE
|
||||
|
||||
@ -330,7 +362,7 @@ type Date_Time
|
||||
|
||||
example_time_of_day = Date_Time.now.time_of_day
|
||||
time_of_day : Time_Of_Day
|
||||
time_of_day self = self.to_localtime_builtin
|
||||
time_of_day self = @Builtin_Method "Date_Time.time_of_day"
|
||||
|
||||
## Returns the number of week of year this date falls into.
|
||||
|
||||
@ -420,7 +452,7 @@ type Date_Time
|
||||
|
||||
example_date = Date_Time.now.date
|
||||
date : Date
|
||||
date self = self.to_localdate_builtin
|
||||
date self = @Builtin_Method "Date_Time.date"
|
||||
|
||||
## ALIAS Change Time Zone
|
||||
|
||||
|
@ -24,7 +24,20 @@ polyglot java import java.lang.ArithmeticException
|
||||
example_between = Duration.between Date_Time.now (Date_Time.new 2010 10 20)
|
||||
between : Date_Time -> Date_Time -> Boolean -> Duration
|
||||
between start_inclusive end_exclusive timezone_aware=True =
|
||||
Duration.between_builtin start_inclusive end_exclusive timezone_aware
|
||||
between_builtin start_inclusive end_exclusive timezone_aware
|
||||
|
||||
## PRIVATE
|
||||
Create an interval representing the duration between two points in time.
|
||||
|
||||
Arguments:
|
||||
- start_inclusive: The start datetime of the duration, included.
|
||||
- end_exclusive: The end datetime of the duration, excluded.
|
||||
- timezone_aware: Whether the duration between two given times should be
|
||||
aware of the timezone, that can be set for start or end times.
|
||||
|
||||
Recommended to use `Duration.between` instead which provides defaults.
|
||||
between_builtin : Date_Time -> Date_Time -> Boolean -> Duration
|
||||
between_builtin start_inclusive end_exclusive timezone_aware = @Builtin_Method "Duration.between_builtin"
|
||||
|
||||
## Create a duration from time units.
|
||||
|
||||
@ -43,7 +56,21 @@ between start_inclusive end_exclusive timezone_aware=True =
|
||||
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
|
||||
new_builtin hours minutes seconds milliseconds nanoseconds
|
||||
|
||||
## PRIVATE
|
||||
Create a duration from time units.
|
||||
|
||||
Arguments:
|
||||
- hours: hours
|
||||
- minutes: minutes
|
||||
- seconds: seconds
|
||||
- milliseconds: milliseconds
|
||||
- nanoseconds: nanoseconds
|
||||
|
||||
Recommended to use `Duration.new` instead which provides defaults.
|
||||
new_builtin : Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Duration
|
||||
new_builtin hours minutes seconds milliseconds nanoseconds = @Builtin_Method "Duration.new_builtin"
|
||||
|
||||
## Create a Duration from hours.
|
||||
hours : Integer -> Duration
|
||||
|
@ -47,9 +47,24 @@ now = @Builtin_Method "Time_Of_Day.now"
|
||||
example_epoch = Time_Of_Day.new hour=9 minute=30
|
||||
new : Integer -> Integer -> Integer -> Integer -> Time_Of_Day ! Time_Error
|
||||
new (hour = 0) (minute = 0) (second = 0) (nanosecond = 0) =
|
||||
Panic.catch_java Any (Time_Of_Day.new_builtin hour minute second nanosecond) java_exception->
|
||||
Panic.catch_java Any (new_builtin hour minute second nanosecond) java_exception->
|
||||
Error.throw (Time_Error_Data java_exception.getMessage)
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Obtains an instance of `Time_Of_Day` from an hour, minute, second
|
||||
and nanosecond.
|
||||
|
||||
Arguments:
|
||||
- hour: The hour-of-day to represent, from 0 to 23.
|
||||
- minute: The minute-of-hour to represent, from 0 to 59.
|
||||
- second: The second-of-minute to represent, from 0 to 59.
|
||||
- nanosecond: The nano-of-second to represent, from 0 to 999,999,999.
|
||||
|
||||
Recommended to use `Time_Of_Day.new` instead which handles potential exceptions.
|
||||
new_builtin : Integer -> Integer -> Integer -> Integer -> Time_Of_Day
|
||||
new_builtin hour minute second nanosecond = @Builtin_Method "Time_Of_Day.new_builtin"
|
||||
|
||||
## Obtains an instance of `Time_Of_Day` from a text such as "10:15".
|
||||
|
||||
Arguments:
|
||||
@ -115,9 +130,21 @@ parse : Text -> Text | Nothing -> Locale -> Time_Of_Day ! Time_Error
|
||||
parse text pattern=Nothing locale=Locale.default =
|
||||
Panic.catch_java Any handler=(java_exception -> Error.throw (Time_Error_Data java_exception.getMessage)) <|
|
||||
case pattern of
|
||||
Nothing -> Time_Of_Day.parse_builtin text
|
||||
Nothing -> parse_builtin text
|
||||
_ : Text -> Time_Utils.parse_time text pattern locale.java_locale
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Obtains an instance of `Time_Of_Day` from a text such as "10:15".
|
||||
|
||||
Arguments:
|
||||
- text: The text to parse as a time of day.
|
||||
|
||||
Recommended to use `Time_Of_Day.parse_builtin` instead which handles potential
|
||||
exceptions and different time formats.
|
||||
parse_builtin : Text -> Time_Of_Day
|
||||
parse_builtin text = @Builtin_Method "Time_Of_Day.parse_builtin"
|
||||
|
||||
## PRIVATE
|
||||
|
||||
This type is a date-time object that represents a time, often viewed
|
||||
@ -204,7 +231,7 @@ type Time_Of_Day
|
||||
|
||||
example_to_time = Time_Of_Day.new 12 30 . to_time (Date.new 2020)
|
||||
to_date_time : Date -> Time_Zone -> Date_Time
|
||||
to_date_time self date (zone=Time_Zone.system) = self.to_time_builtin date zone
|
||||
to_date_time self date (zone=Time_Zone.system) = self.to_date_time_builtin date zone
|
||||
|
||||
## Add the specified amount of time to this instant to get a new instant.
|
||||
|
||||
|
@ -60,7 +60,22 @@ utc = parse "UTC"
|
||||
example_new = Zone.new 1 1 50
|
||||
new : Integer -> Integer -> Integer -> Time_Zone
|
||||
new (hours = 0) (minutes = 0) (seconds = 0) =
|
||||
Time_Zone.new_builtin hours minutes seconds
|
||||
new_builtin hours minutes seconds
|
||||
|
||||
## PRIVATE
|
||||
Obtains an instance of `Time_Zone` using an offset in hours, minutes and seconds
|
||||
from the UTC zone.
|
||||
|
||||
Arguments:
|
||||
- hours: The timezone offset in hours from UTC, from -18 to +18.
|
||||
- minutes: The timezone offset in minutes from the nearest hour, from 0 to
|
||||
±59. The sign must match that of the hours argument.
|
||||
- seconds: The timezone offset in seconds from the nearest minute, from 0 to
|
||||
±59. The sign must match that of the minutes argument.
|
||||
|
||||
Recommended to use `Time_Zone.new` instead which provides defaults.
|
||||
new_builtin : Integer -> Integer -> Integer -> Time_Zone
|
||||
new_builtin hours minutes seconds = @Builtin_Method "Time_Zone.new_builtin"
|
||||
|
||||
## ALIAS Time Zone from Text
|
||||
|
||||
@ -96,10 +111,21 @@ new (hours = 0) (minutes = 0) (seconds = 0) =
|
||||
from Standard.Base import Time_Zone
|
||||
|
||||
example_parse = Time_Zone.parse "+03:02:01"
|
||||
parse : Text -> Time_Zone
|
||||
parse : Text -> Time_Zone ! Time_Error
|
||||
parse text =
|
||||
Panic.catch_java Any handler=(java_exception -> Error.throw (Time_Error_Data java_exception.getMessage)) <|
|
||||
Time_Zone.parse_builtin text
|
||||
parse_builtin text
|
||||
|
||||
## PRIVATE
|
||||
|
||||
This method parses the ID producing a `Time_Zone`.
|
||||
|
||||
Arguments:
|
||||
- text: The text representing a zone identifier.
|
||||
|
||||
Recommended to use `Time_Zone.parse` instead which handles potential exceptions.
|
||||
parse_builtin : Text -> Time_Zone
|
||||
parse_builtin text = @Builtin_Method "Time_Zone.parse_builtin"
|
||||
|
||||
## PRIVATE
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Data.Array
|
||||
import Standard.Base.Data.Index_Sub_Range
|
||||
import Standard.Base.Random
|
||||
|
||||
@ -26,7 +27,7 @@ polyglot java import java.lang.ClassCastException
|
||||
|
||||
Vector.new my_vec.length (ix -> my_vec.at ix)
|
||||
new : Number -> (Number -> Any) -> Vector Any
|
||||
new length constructor = @Builtin_Method "Vector.new_builtin"
|
||||
new length constructor = @Builtin_Method "Vector.new"
|
||||
|
||||
## ADVANCED
|
||||
|
||||
@ -453,7 +454,7 @@ type Vector a
|
||||
self.fold 0 i-> vec->
|
||||
Array.copy vec.to_array 0 arr i vec.length
|
||||
i + vec.length
|
||||
Vector.from_polyglot_array arr
|
||||
from_polyglot_array arr
|
||||
|
||||
## Applies a function to each element of the vector, returning the vector
|
||||
of results.
|
||||
@ -568,7 +569,7 @@ type Vector a
|
||||
_ : Vector ->
|
||||
eq_at i = self.at i == that.at i
|
||||
if self.length == that.length then 0.up_to self.length . all eq_at else False
|
||||
_ : Array ->
|
||||
_ : Array.Array ->
|
||||
eq_at i = self.at i == that.at i
|
||||
if self.length == that.length then 0.up_to self.length . all eq_at else False
|
||||
_ -> False
|
||||
@ -589,7 +590,7 @@ type Vector a
|
||||
arr = Array.new (self_len + that.length)
|
||||
Array.copy self.to_array 0 arr 0 self_len
|
||||
Array.copy that.to_array 0 arr self_len that.length
|
||||
Vector.from_polyglot_array arr
|
||||
from_polyglot_array arr
|
||||
|
||||
## Add `element` to the beginning of `self` vector.
|
||||
|
||||
@ -867,7 +868,7 @@ type Vector a
|
||||
|
||||
handle_incomparable_value <|
|
||||
new_vec_arr.sort compare
|
||||
Vector.from_polyglot_array new_vec_arr
|
||||
from_polyglot_array new_vec_arr
|
||||
|
||||
## UNSTABLE
|
||||
Keeps only unique elements within the Vector, removing any duplicates.
|
||||
|
@ -766,6 +766,8 @@ type Time_Error
|
||||
epoch_start : Time_Error
|
||||
epoch_start = Time_Error_Data "Epoch start underflow"
|
||||
|
||||
to_display_text : Text
|
||||
to_display_text self = self.error_message
|
||||
|
||||
## TODO Dubious constructor export
|
||||
from project.Error.Common.Unsupported_File_Type import all
|
||||
|
@ -87,6 +87,7 @@ export project.Error.Problem_Behavior
|
||||
export project.IO
|
||||
export project.Math
|
||||
export project.Meta
|
||||
export project.Polyglot
|
||||
export project.Polyglot.Java
|
||||
export project.Runtime
|
||||
export project.Runtime.State
|
||||
@ -119,7 +120,6 @@ from project.Data.Text.Span export all
|
||||
from project.Error.Common export all
|
||||
from project.Function export all
|
||||
from project.Nothing export all
|
||||
from project.Polyglot export all
|
||||
from project.Runtime.Extensions export all
|
||||
from project.System.File_Format export File_Format, Plain_Text_Format, Plain_Text, Bytes, Infer, Auto_Detect
|
||||
from project.Data.Index_Sub_Range export First, Last
|
||||
|
@ -330,8 +330,8 @@ is_a value typ = if is_same_object value typ then True else
|
||||
_ : Duration.Duration -> typ.is_same_object_as Duration.Duration
|
||||
_ : Time_Of_Day.Time_Of_Day -> typ.is_same_object_as Time_Of_Day.Time_Of_Day
|
||||
_ : Time_Zone.Time_Zone -> typ.is_same_object_as Time_Zone.Time_Zone
|
||||
Base.Polyglot ->
|
||||
typ==Base.Polyglot || java_instance_check value typ
|
||||
Base.Polyglot.Polyglot ->
|
||||
typ==Base.Polyglot.Polyglot || java_instance_check value typ
|
||||
_ ->
|
||||
meta_val = meta value
|
||||
case meta_val of
|
||||
@ -361,7 +361,7 @@ java_instance_check value typ =
|
||||
Arguments:
|
||||
- value: the value to get the type of.
|
||||
type_of : Any -> Any
|
||||
type_of value = @Builtin_Method "Meta.type_of_builtin"
|
||||
type_of value = @Builtin_Method "Meta.type_of"
|
||||
|
||||
# TODO Dubious constructor export
|
||||
from project.Meta.Language import all
|
||||
@ -427,17 +427,6 @@ is_polyglot value = @Builtin_Method "Meta.is_polyglot"
|
||||
is_unresolved_symbol : Any -> Boolean
|
||||
is_unresolved_symbol value = @Builtin_Method "Meta.is_unresolved_symbol"
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Returns a Text representing the source location of a stack frame above
|
||||
the call.
|
||||
|
||||
Arguments:
|
||||
- frames_to_skip: how many frames on the stack to skip. Called with 0
|
||||
will return exact location of the call.
|
||||
get_source_location_builtin : Integer -> Text
|
||||
get_source_location_builtin frames_to_skip = @Builtin_Method "Meta.get_source_location_builtin"
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Returns a Text representing the source location of a stack frame above
|
||||
@ -455,6 +444,17 @@ get_source_location : Integer -> Text
|
||||
get_source_location skip_frames =
|
||||
get_source_location_builtin skip_frames+1
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Returns a Text representing the source location of a stack frame above
|
||||
the call.
|
||||
|
||||
Arguments:
|
||||
- frames_to_skip: how many frames on the stack to skip. Called with 0
|
||||
will return exact location of the call.
|
||||
get_source_location_builtin : Integer -> Text
|
||||
get_source_location_builtin frames_to_skip = @Builtin_Method "Meta.get_source_location_builtin"
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Displays the type of the provided value as text.
|
||||
|
@ -1,6 +1,6 @@
|
||||
## Utilities for working with Java polyglot objects.
|
||||
type Java
|
||||
## Adds the provided entry to the host class path.
|
||||
|
||||
## Adds the provided entry to the host class path.
|
||||
|
||||
Arguments:
|
||||
- path: The java classpath entry to add.
|
||||
@ -12,8 +12,8 @@ type Java
|
||||
Adding Random to the classpath.
|
||||
|
||||
Java.add_to_class_path "java.util.Random"
|
||||
add_to_class_path : Text -> Nothing
|
||||
add_to_class_path path = @Builtin_Method "Java.add_to_class_path"
|
||||
add_to_class_path : Text -> Nothing
|
||||
add_to_class_path path = @Builtin_Method "Java.add_to_class_path"
|
||||
|
||||
## Looks up a java symbol on the classpath by name.
|
||||
|
||||
|
@ -1,28 +0,0 @@
|
||||
from Standard.Base import Polyglot, Array
|
||||
|
||||
## TODO Dubious constructor export
|
||||
from project.Polyglot.Proxy_Polyglot_Array.Proxy_Polyglot_Array import all
|
||||
from project.Polyglot.Proxy_Polyglot_Array.Proxy_Polyglot_Array export all
|
||||
|
||||
## Advanced
|
||||
|
||||
Wrapper for Polyglot Arrays
|
||||
type Proxy_Polyglot_Array
|
||||
|
||||
Proxy_Polyglot_Array_Data arr
|
||||
|
||||
## Returns the number of elements stored in this Polyglot Array.
|
||||
|
||||
length : Number
|
||||
length self =
|
||||
Polyglot.get_array_size self.arr
|
||||
|
||||
## Gets an element from this Polyglot Array at a specified index (0-based).
|
||||
|
||||
at : Number -> Any
|
||||
at self index =
|
||||
Polyglot.read_array_element self.arr index
|
||||
|
||||
to_array : Array Any
|
||||
to_array self =
|
||||
self.arr
|
@ -1,12 +1,13 @@
|
||||
from Standard.Base import all
|
||||
|
||||
import Standard.Base.System.File.Option
|
||||
import Standard.Base.System.File.File_Permissions
|
||||
import Standard.Base.Data.Array
|
||||
import Standard.Base.Data.Text.Text_Sub_Range
|
||||
from Standard.Base.Error.Common import Unsupported_File_Type
|
||||
from Standard.Base.Error.Problem_Behavior import Report_Warning
|
||||
import Standard.Base.Runtime.Resource
|
||||
from Standard.Base.Runtime.Resource import Managed_Resource
|
||||
from Standard.Base.Error.Common import Unsupported_File_Type
|
||||
import Standard.Base.System.File.Option
|
||||
import Standard.Base.System.File.File_Permissions
|
||||
|
||||
polyglot java import org.enso.base.Array_Builder
|
||||
polyglot java import org.enso.base.Encoding_Utils
|
||||
@ -391,14 +392,6 @@ type File
|
||||
creation_time self =
|
||||
handle_java_exceptions self <| self.creation_time_builtin
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Builtin method that gets this file's creation time.
|
||||
Recommended to use `File.creation_time` instead which handles potential
|
||||
exceptions.
|
||||
creation_time_builtin : File -> ZonedDateTime
|
||||
creation_time_builtin self = @Builtin_Method "File.creation_time_builtin"
|
||||
|
||||
## Gets the last modified time of a file.
|
||||
|
||||
> Example
|
||||
@ -411,14 +404,6 @@ type File
|
||||
last_modified_time self =
|
||||
handle_java_exceptions self <| self.last_modified_time_builtin
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Builtin method that gets this file's last modified time.
|
||||
Recommended to use `File.last_modified_time` instead which handles
|
||||
potential exceptions.
|
||||
last_modified_time_builtin : ZonedDateTime
|
||||
last_modified_time_builtin self = @Builtin_Method "File.last_modified_time_builtin"
|
||||
|
||||
## Gets the POSIX permissions associated with the file.
|
||||
|
||||
> Example
|
||||
@ -431,15 +416,6 @@ type File
|
||||
posix_permissions self =
|
||||
File_Permissions.from_java_set self.posix_permissions_builtin
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Builtin method that gets this file's POSIX permissions as a Java Set.
|
||||
Recommended to use `File.posix_permissions` instead which handles
|
||||
potential exceptions and converts an Enso representation of the
|
||||
permissions.
|
||||
posix_permissions_builtin : Set
|
||||
posix_permissions_builtin self = @Builtin_Method "File.posix_permissions_builtin"
|
||||
|
||||
## Checks whether the file exists and is a directory.
|
||||
|
||||
> Example
|
||||
@ -593,13 +569,6 @@ type File
|
||||
delete self =
|
||||
handle_java_exceptions self self.delete_builtin
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Builtin method that deletes the file.
|
||||
Recommended to use `File.delete` instead which handles potential exceptions.
|
||||
delete_builtin : Nothing
|
||||
delete_builtin self = @Builtin_Method "File.delete_builtin"
|
||||
|
||||
## Moves the file to the specified destination.
|
||||
|
||||
Arguments:
|
||||
@ -614,13 +583,6 @@ type File
|
||||
self.copy_builtin destination copy_options
|
||||
False -> self.copy_builtin destination Array.empty
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Builtin method that copies this file to a new destination.
|
||||
Recommended to use `File.copy_to` instead which handles potential exceptions.
|
||||
copy_builtin : File -> Array Any -> Nothing
|
||||
copy_builtin self destination copy_options = @Builtin_Method "File.copy_builtin"
|
||||
|
||||
## Moves the file to the specified destination.
|
||||
|
||||
Arguments:
|
||||
@ -635,13 +597,6 @@ type File
|
||||
self.move_builtin destination copy_options
|
||||
False -> self.move_builtin destination Array.empty
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Builtin method that moves this file to a new destination.
|
||||
Recommended to use `File.move_to` instead which handles potential exceptions.
|
||||
move_builtin : File -> Array Any -> Nothing
|
||||
move_builtin self destination copy_options = @Builtin_Method "File.move_builtin"
|
||||
|
||||
## Deletes the file if it exists on disk.
|
||||
|
||||
If the file is a directory, it must be empty, otherwise a `Panic` will
|
||||
@ -700,10 +655,6 @@ type File
|
||||
handle_java_exceptions self <|
|
||||
Vector.from_polyglot_array (self.read_last_bytes_builtin n)
|
||||
|
||||
## PRIVATE
|
||||
read_last_bytes_builtin : Integer -> Array
|
||||
read_last_bytes_builtin self n = @Builtin_Method "File.read_last_bytes_builtin"
|
||||
|
||||
## Lists files contained in the directory denoted by this file.
|
||||
|
||||
Arguments:
|
||||
@ -790,12 +741,6 @@ type File
|
||||
list_immediate_children : Vector.Vector File
|
||||
list_immediate_children self = Vector.from_polyglot_array (self.list_immediate_children_array)
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Utility function that lists immediate children of a directory.
|
||||
list_immediate_children_array : Array File
|
||||
list_immediate_children_array self = @Builtin_Method "File.list_immediate_children_array"
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Return the absolute path of this File
|
||||
|
@ -1,4 +1,5 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Data.Array
|
||||
|
||||
from project.Internal.Vector_Builder.Vector_Builder import Leaf, Append
|
||||
|
||||
|
@ -344,10 +344,10 @@ class BuiltinTypesTest
|
||||
val requestId = UUID.randomUUID()
|
||||
|
||||
val metadata = new Metadata
|
||||
val idMain = metadata.addItem(37, 19)
|
||||
val idMain = metadata.addItem(39, 19)
|
||||
|
||||
val code =
|
||||
"""from Standard.Base import all
|
||||
"""import Standard.Base.Data.Array
|
||||
|
|
||||
|main =
|
||||
| Array.new_1 42
|
||||
@ -370,10 +370,11 @@ class BuiltinTypesTest
|
||||
val requestId = UUID.randomUUID()
|
||||
|
||||
val metadata = new Metadata
|
||||
val idMain = metadata.addItem(37, 34)
|
||||
val idMain = metadata.addItem(69, 34)
|
||||
|
||||
val code =
|
||||
"""from Standard.Base import all
|
||||
|import Standard.Base.Data.Array
|
||||
|
|
||||
|main =
|
||||
| Vector.from_array Array.empty
|
||||
|
@ -13,7 +13,11 @@ import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.callable.CallerInfo;
|
||||
import org.enso.interpreter.runtime.state.State;
|
||||
|
||||
@BuiltinMethod(type = "Debug", name = "breakpoint", description = "Instrumentation marker node.")
|
||||
@BuiltinMethod(
|
||||
type = "Debug",
|
||||
name = "breakpoint",
|
||||
description = "Instrumentation marker node.",
|
||||
autoRegister = false)
|
||||
@GenerateWrapper
|
||||
public abstract class DebugBreakpointNode extends Node implements InstrumentableNode {
|
||||
/**
|
||||
|
@ -12,7 +12,8 @@ import org.enso.interpreter.runtime.state.State;
|
||||
@BuiltinMethod(
|
||||
type = "Debug",
|
||||
name = "eval",
|
||||
description = "Evaluates an expression passed as a Text argument, in the caller frame.")
|
||||
description = "Evaluates an expression passed as a Text argument, in the caller frame.",
|
||||
autoRegister = false)
|
||||
public class DebugEvalNode extends Node {
|
||||
private @Child EvalNode evalNode = EvalNode.build();
|
||||
private @Child ExpectTextNode expectTextNode = ExpectTextNode.build();
|
||||
|
@ -9,10 +9,10 @@ import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||
import org.enso.interpreter.runtime.data.text.Text;
|
||||
import org.enso.interpreter.runtime.type.TypesGen;
|
||||
|
||||
@BuiltinMethod(type = "Module_Does_Not_Exist_Error", name = "to_display_text")
|
||||
public abstract class ModuleDoesNotExistErrorToDisplayTextNode extends Node {
|
||||
static ModuleDoesNotExistErrorToDisplayTextNode build() {
|
||||
return ModuleDoesNotExistErrorToDisplayTextNodeGen.create();
|
||||
@BuiltinMethod(type = "Module_Does_Not_Exist", name = "to_display_text")
|
||||
public abstract class ModuleDoesNotExistToDisplayTextNode extends Node {
|
||||
static ModuleDoesNotExistToDisplayTextNode build() {
|
||||
return ModuleDoesNotExistToDisplayTextNodeGen.create();
|
||||
}
|
||||
|
||||
abstract Text execute(Object self);
|
@ -9,7 +9,7 @@ import org.enso.interpreter.runtime.callable.atom.Atom;
|
||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||
import org.enso.interpreter.runtime.data.text.Text;
|
||||
|
||||
@BuiltinMethod(type = "Uninitialized_State_Error", name = "to_display_text")
|
||||
@BuiltinMethod(type = "Uninitialized_State", name = "to_display_text")
|
||||
public abstract class UninitializedStateErrorToDisplayTextNode extends Node {
|
||||
static UninitializedStateErrorToDisplayTextNode build() {
|
||||
return UninitializedStateErrorToDisplayTextNodeGen.create();
|
||||
|
@ -2,14 +2,10 @@ package org.enso.interpreter.node.expression.builtin.immutable;
|
||||
|
||||
import com.oracle.truffle.api.dsl.*;
|
||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
|
||||
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
||||
import com.oracle.truffle.api.library.CachedLibrary;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.*;
|
||||
import org.enso.interpreter.epb.node.CoercePrimitiveNode;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.mutable.CoerceArrayNode;
|
||||
import org.enso.interpreter.node.expression.foreign.CoerceNothing;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
@ -18,7 +14,8 @@ import org.enso.interpreter.runtime.data.Vector;
|
||||
@BuiltinMethod(
|
||||
type = "Vector",
|
||||
name = "from_array",
|
||||
description = "Creates a Vector by copying Array content.")
|
||||
description = "Creates a Vector by copying Array content.",
|
||||
autoRegister = false)
|
||||
public abstract class FromArrayBuiltinVectorNode extends Node {
|
||||
static FromArrayBuiltinVectorNode build() {
|
||||
return FromArrayBuiltinVectorNodeGen.create();
|
||||
|
@ -4,7 +4,7 @@ import com.oracle.truffle.api.dsl.*;
|
||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||
import com.oracle.truffle.api.library.CachedLibrary;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.*;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.data.Vector;
|
||||
@ -12,7 +12,9 @@ import org.enso.interpreter.runtime.data.Vector;
|
||||
@BuiltinMethod(
|
||||
type = "Vector",
|
||||
name = "from_polyglot_array",
|
||||
description = "Returns an Array representation of this Vector.")
|
||||
description =
|
||||
"Creates a Vector by providing its underlying storage as a polyglot array. The underlying array should be guaranteed to never be mutated.",
|
||||
autoRegister = false)
|
||||
public abstract class FromPolyglotArrayBuiltinVectorNode extends Node {
|
||||
|
||||
static FromPolyglotArrayBuiltinVectorNode build() {
|
||||
|
@ -12,13 +12,13 @@ import org.enso.interpreter.Constants;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode;
|
||||
import org.enso.interpreter.node.expression.builtin.mutable.CoerceArrayNode;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Polyglot",
|
||||
name = "execute",
|
||||
description = "Executes a polyglot function object (e.g. a lambda).")
|
||||
description = "Executes a polyglot function object (e.g. a lambda).",
|
||||
autoRegister = false)
|
||||
public abstract class ExecuteNode extends Node {
|
||||
private @Child InteropLibrary library =
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
|
@ -13,7 +13,8 @@ import org.enso.interpreter.runtime.error.PanicException;
|
||||
@BuiltinMethod(
|
||||
type = "Polyglot",
|
||||
name = "get_array_size",
|
||||
description = "Returns the size of a polyglot array.")
|
||||
description = "Returns the size of a polyglot array.",
|
||||
autoRegister = false)
|
||||
public class GetArraySizeNode extends Node {
|
||||
private @Child InteropLibrary library =
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
|
@ -14,7 +14,8 @@ import org.enso.interpreter.runtime.error.PanicException;
|
||||
@BuiltinMethod(
|
||||
type = "Polyglot",
|
||||
name = "get_executable_name",
|
||||
description = "Returns the executable name of a polyglot object.")
|
||||
description = "Returns the executable name of a polyglot object.",
|
||||
autoRegister = false)
|
||||
public class GetExecutableNameNode extends Node {
|
||||
private @Child InteropLibrary functionsLibrary =
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
|
@ -13,7 +13,8 @@ import org.enso.interpreter.runtime.error.PanicException;
|
||||
@BuiltinMethod(
|
||||
type = "Polyglot",
|
||||
name = "get_member",
|
||||
description = "Gets a member by name from a polyglot object.")
|
||||
description = "Gets a member by name from a polyglot object.",
|
||||
autoRegister = false)
|
||||
public class GetMemberNode extends Node {
|
||||
private @Child InteropLibrary library =
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
|
@ -10,7 +10,8 @@ import org.enso.interpreter.runtime.data.Array;
|
||||
@BuiltinMethod(
|
||||
type = "Polyglot",
|
||||
name = "get_members",
|
||||
description = "Returns a polyglot array of the object's member names.")
|
||||
description = "Returns a polyglot array of the object's member names.",
|
||||
autoRegister = false)
|
||||
public class GetMembersNode extends Node {
|
||||
private @Child InteropLibrary library =
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
|
@ -14,7 +14,8 @@ import org.enso.interpreter.runtime.error.PanicException;
|
||||
@BuiltinMethod(
|
||||
type = "Polyglot",
|
||||
name = "get_source_location",
|
||||
description = "Returns the source location of a polyglot object.")
|
||||
description = "Returns the source location of a polyglot object.",
|
||||
autoRegister = false)
|
||||
public class GetSourceLocationNode extends Node {
|
||||
private @Child InteropLibrary library =
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
|
@ -9,7 +9,8 @@ import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
@BuiltinMethod(
|
||||
type = "Polyglot",
|
||||
name = "has_source_location",
|
||||
description = "Checks if an object has a source location.")
|
||||
description = "Checks if an object has a source location.",
|
||||
autoRegister = false)
|
||||
public class HasSourceLocationNode extends Node {
|
||||
private @Child InteropLibrary library =
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
|
@ -16,7 +16,8 @@ import org.enso.interpreter.runtime.error.PanicException;
|
||||
@BuiltinMethod(
|
||||
type = "Polyglot",
|
||||
name = "new",
|
||||
description = "Instantiates a polyglot constructor.")
|
||||
description = "Instantiates a polyglot constructor.",
|
||||
autoRegister = false)
|
||||
public abstract class InstantiateNode extends Node {
|
||||
|
||||
private @Child InteropLibrary library =
|
||||
|
@ -18,7 +18,8 @@ import org.enso.interpreter.runtime.error.PanicException;
|
||||
@BuiltinMethod(
|
||||
type = "Polyglot",
|
||||
name = "invoke",
|
||||
description = "Invokes a polyglot method by name, dispatching by the target argument.")
|
||||
description = "Invokes a polyglot method by name, dispatching by the target argument.",
|
||||
autoRegister = false)
|
||||
public abstract class InvokeNode extends Node {
|
||||
private @Child InteropLibrary library =
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
|
@ -11,7 +11,8 @@ import org.enso.interpreter.runtime.Context;
|
||||
@BuiltinMethod(
|
||||
type = "Polyglot",
|
||||
name = "is_language_installed",
|
||||
description = "Checks if a polyglot language is installed in the runtime environment.")
|
||||
description = "Checks if a polyglot language is installed in the runtime environment.",
|
||||
autoRegister = false)
|
||||
public abstract class IsLanguageInstalledNode extends Node {
|
||||
|
||||
static IsLanguageInstalledNode build() {
|
||||
|
@ -16,7 +16,8 @@ import org.enso.interpreter.runtime.error.PanicException;
|
||||
@BuiltinMethod(
|
||||
type = "Polyglot",
|
||||
name = "read_array_element",
|
||||
description = "Read a value from the array specified by the index.")
|
||||
description = "Read a value from the array specified by the index.",
|
||||
autoRegister = false)
|
||||
public class ReadArrayElementNode extends Node {
|
||||
private @Child InteropLibrary library =
|
||||
InteropLibrary.getFactory().createDispatched(Constants.CacheSizes.BUILTIN_INTEROP_DISPATCH);
|
||||
|
@ -13,22 +13,23 @@ import java.io.File;
|
||||
@BuiltinMethod(
|
||||
type = "Java",
|
||||
name = "add_to_class_path",
|
||||
description = "Adds a path to the host class path.")
|
||||
description = "Adds a path to the host class path.",
|
||||
autoRegister = false)
|
||||
public abstract class AddToClassPathNode extends Node {
|
||||
|
||||
static AddToClassPathNode build() {
|
||||
return AddToClassPathNodeGen.create();
|
||||
}
|
||||
|
||||
abstract Object execute(Object path);
|
||||
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
@Specialization
|
||||
Object doExecute(Object self, Object path, @Cached ExpectStringNode expectStringNode) {
|
||||
Object doExecute(Object path, @Cached ExpectStringNode expectStringNode) {
|
||||
Context context = Context.get(this);
|
||||
context
|
||||
.getEnvironment()
|
||||
.addToHostClassPath(context.getTruffleFile(new File(expectStringNode.execute(path))));
|
||||
return context.getBuiltins().nothing();
|
||||
}
|
||||
|
||||
abstract Object execute(Object self, Object path);
|
||||
}
|
||||
|
@ -7,16 +7,20 @@ import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.text.util.ExpectStringNode;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
|
||||
@BuiltinMethod(type = "Java", name = "lookup_class", description = "Looks up a Java symbol.")
|
||||
@BuiltinMethod(
|
||||
type = "Java",
|
||||
name = "lookup_class",
|
||||
description = "Looks up a Java symbol.",
|
||||
autoRegister = false)
|
||||
public abstract class LookupClassNode extends Node {
|
||||
static LookupClassNode build() {
|
||||
return LookupClassNodeGen.create();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object doExecute(Object self, Object name, @Cached("build()") ExpectStringNode expectStringNode) {
|
||||
Object doExecute(Object name, @Cached("build()") ExpectStringNode expectStringNode) {
|
||||
return Context.get(this).getEnvironment().lookupHostSymbol(expectStringNode.execute(name));
|
||||
}
|
||||
|
||||
abstract Object execute(Object self, Object name);
|
||||
abstract Object execute(Object name);
|
||||
}
|
||||
|
@ -22,7 +22,8 @@ import org.enso.interpreter.runtime.type.TypesGen;
|
||||
@BuiltinMethod(
|
||||
type = "IO",
|
||||
name = "print_err",
|
||||
description = "Prints its argument to standard error.")
|
||||
description = "Prints its argument to standard error.",
|
||||
autoRegister = false)
|
||||
public abstract class PrintErrNode extends Node {
|
||||
static PrintErrNode build() {
|
||||
return PrintErrNodeGen.create();
|
||||
|
@ -19,7 +19,11 @@ import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
|
||||
import org.enso.interpreter.runtime.state.State;
|
||||
import org.enso.interpreter.runtime.type.TypesGen;
|
||||
|
||||
@BuiltinMethod(type = "IO", name = "println", description = "Prints its argument to standard out.")
|
||||
@BuiltinMethod(
|
||||
type = "IO",
|
||||
name = "println",
|
||||
description = "Prints its argument to standard out.",
|
||||
autoRegister = false)
|
||||
public abstract class PrintlnNode extends Node {
|
||||
private @Child InvokeCallableNode invokeCallableNode =
|
||||
InvokeCallableNode.build(
|
||||
|
@ -10,7 +10,11 @@ import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.data.text.Text;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
|
||||
@BuiltinMethod(type = "IO", name = "readln", description = "Reads a line from standard in.")
|
||||
@BuiltinMethod(
|
||||
type = "IO",
|
||||
name = "readln",
|
||||
description = "Reads a line from standard in.",
|
||||
autoRegister = false)
|
||||
public abstract class ReadlnNode extends Node {
|
||||
static ReadlnNode build() {
|
||||
return ReadlnNodeGen.create();
|
||||
|
@ -11,7 +11,8 @@ import org.enso.interpreter.runtime.scope.ModuleScope;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "create_unresolved_symbol",
|
||||
description = "Creates a new unresolved symbol node")
|
||||
description = "Creates a new unresolved symbol node",
|
||||
autoRegister = false)
|
||||
public class CreateUnresolvedSymbolNode extends Node {
|
||||
private @Child ExpectStringNode expectStringNode = ExpectStringNode.build();
|
||||
|
||||
|
@ -9,7 +9,8 @@ import org.enso.interpreter.runtime.data.Type;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "get_atom_constructor",
|
||||
description = "Gets the constructor of an atom.")
|
||||
description = "Gets the constructor of an atom.",
|
||||
autoRegister = false)
|
||||
public abstract class GetAtomConstructorNode extends Node {
|
||||
abstract Object execute(Object atom);
|
||||
|
||||
|
@ -8,7 +8,8 @@ import org.enso.interpreter.runtime.data.Array;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "get_atom_fields",
|
||||
description = "Gets the fields of an unresolved atom.")
|
||||
description = "Gets the fields of an unresolved atom.",
|
||||
autoRegister = false)
|
||||
public class GetAtomFieldsNode extends Node {
|
||||
Array execute(Atom atom) {
|
||||
return new Array(atom.getFields());
|
||||
|
@ -10,7 +10,8 @@ import org.enso.interpreter.runtime.data.text.Text;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "get_constructor_fields",
|
||||
description = "Gets the field names of a constructor.")
|
||||
description = "Gets the field names of a constructor.",
|
||||
autoRegister = false)
|
||||
public class GetConstructorFieldNamesNode extends Node {
|
||||
Array execute(AtomConstructor atom_constructor) {
|
||||
ArgumentDefinition[] fields = atom_constructor.getFields();
|
||||
|
@ -10,7 +10,8 @@ import org.enso.interpreter.runtime.data.text.Text;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "get_constructor_name",
|
||||
description = "Gets the name of a constructor.")
|
||||
description = "Gets the name of a constructor.",
|
||||
autoRegister = false)
|
||||
public abstract class GetConstructorNameNode extends Node {
|
||||
static GetConstructorNameNode build() {
|
||||
return GetConstructorNameNodeGen.create();
|
||||
|
@ -9,7 +9,8 @@ import org.enso.interpreter.runtime.data.text.Text;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "get_polyglot_language",
|
||||
description = "Returns a text representation of a language of origin of a given value.")
|
||||
description = "Returns a text representation of a language of origin of a given value.",
|
||||
autoRegister = false)
|
||||
public abstract class GetPolyglotLanguageNode extends Node {
|
||||
static GetPolyglotLanguageNode build() {
|
||||
return GetPolyglotLanguageNodeGen.create();
|
||||
|
@ -9,7 +9,8 @@ import org.enso.interpreter.runtime.type.Types;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "get_qualified_type_name",
|
||||
description = "Returns a qualified type name of the given value.")
|
||||
description = "Returns a qualified type name of the given value.",
|
||||
autoRegister = false)
|
||||
public class GetQualifiedTypeNameNode extends Node {
|
||||
Text execute(@AcceptsError Object value) {
|
||||
var typeName = Types.getName(value);
|
||||
|
@ -7,7 +7,11 @@ import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode;
|
||||
import org.enso.interpreter.runtime.data.text.Text;
|
||||
|
||||
@BuiltinMethod(type = "Meta", name = "get_simple_type_name", description = "Pretty prints a type.")
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "get_simple_type_name",
|
||||
description = "Pretty prints a type.",
|
||||
autoRegister = false)
|
||||
public class GetSimpleTypeNameNode extends Node {
|
||||
@Child @CompilationFinal TypeToDisplayTextNode displayTypeNode = TypeToDisplayTextNode.build();
|
||||
|
||||
|
@ -11,7 +11,8 @@ import org.enso.interpreter.runtime.data.text.Text;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "get_source_location_builtin",
|
||||
description = "Returns a textual representation of the location of the callsite.")
|
||||
description = "Returns a textual representation of the location of the callsite.",
|
||||
autoRegister = false)
|
||||
public class GetSourceLocationNode extends Node {
|
||||
|
||||
Text execute(long frames_to_skip) {
|
||||
|
@ -15,7 +15,8 @@ import org.enso.interpreter.runtime.error.PanicException;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "get_unresolved_symbol_name",
|
||||
description = "Gets the name of an unresolved symbol")
|
||||
description = "Gets the name of an unresolved symbol",
|
||||
autoRegister = false)
|
||||
public abstract class GetUnresolvedSymbolNameNode extends Node {
|
||||
static GetUnresolvedSymbolNameNode build() {
|
||||
return GetUnresolvedSymbolNameNodeGen.create();
|
||||
|
@ -14,7 +14,8 @@ import org.enso.interpreter.runtime.scope.ModuleScope;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "get_unresolved_symbol_scope",
|
||||
description = "Gets the scope of an unresolved symbol")
|
||||
description = "Gets the scope of an unresolved symbol",
|
||||
autoRegister = false)
|
||||
public abstract class GetUnresolvedSymbolScopeNode extends Node {
|
||||
static GetUnresolvedSymbolScopeNode build() {
|
||||
return GetUnresolvedSymbolScopeNodeGen.create();
|
||||
|
@ -8,7 +8,8 @@ import org.enso.interpreter.runtime.type.TypesGen;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "is_atom_constructor",
|
||||
description = "Checks if the argument is a constructor.")
|
||||
description = "Checks if the argument is a constructor.",
|
||||
autoRegister = false)
|
||||
public class IsAtomConstructorNode extends Node {
|
||||
boolean execute(@AcceptsError Object value) {
|
||||
return TypesGen.isAtomConstructor(value);
|
||||
|
@ -6,7 +6,11 @@ import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.callable.atom.Atom;
|
||||
import org.enso.interpreter.runtime.data.Type;
|
||||
|
||||
@BuiltinMethod(type = "Meta", name = "is_atom", description = "Checks if the argument is an atom")
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "is_atom",
|
||||
description = "Checks if the argument is an atom",
|
||||
autoRegister = false)
|
||||
public class IsAtomNode extends Node {
|
||||
boolean execute(@AcceptsError Object value) {
|
||||
return value instanceof Atom || value instanceof Type;
|
||||
|
@ -8,7 +8,8 @@ import org.enso.interpreter.runtime.type.TypesGen;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "is_error",
|
||||
description = "Checks if the argument is an error.")
|
||||
description = "Checks if the argument is an error.",
|
||||
autoRegister = false)
|
||||
public class IsErrorNode extends Node {
|
||||
boolean execute(@AcceptsError Object value) {
|
||||
return TypesGen.isDataflowError(value);
|
||||
|
@ -9,7 +9,8 @@ import org.enso.interpreter.runtime.Context;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "is_polyglot",
|
||||
description = "Checks if the argument is a polyglot value.")
|
||||
description = "Checks if the argument is a polyglot value.",
|
||||
autoRegister = false)
|
||||
public abstract class IsPolyglotNode extends Node {
|
||||
static IsPolyglotNode build() {
|
||||
return IsPolyglotNodeGen.create();
|
||||
|
@ -10,7 +10,8 @@ import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "is_same_object",
|
||||
description = "Checks if the two arguments share an underlying reference.")
|
||||
description = "Checks if the two arguments share an underlying reference.",
|
||||
autoRegister = false)
|
||||
public abstract class IsSameObjectNode extends Node {
|
||||
|
||||
public static IsSameObjectNode build() {
|
||||
|
@ -8,7 +8,8 @@ import org.enso.interpreter.runtime.type.TypesGen;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "is_unresolved_symbol",
|
||||
description = "Checks if the argument is an unresolved symbol.")
|
||||
description = "Checks if the argument is an unresolved symbol.",
|
||||
autoRegister = false)
|
||||
public class IsUnresolvedSymbolNode extends Node {
|
||||
boolean execute(@AcceptsError Object value) {
|
||||
return TypesGen.isUnresolvedSymbol(value) || TypesGen.isUnresolvedConversion(value);
|
||||
|
@ -11,7 +11,8 @@ import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "new_atom",
|
||||
description = "Creates a new atom with given constructor and fields.")
|
||||
description = "Creates a new atom with given constructor and fields.",
|
||||
autoRegister = false)
|
||||
public abstract class NewAtomInstanceNode extends Node {
|
||||
|
||||
static NewAtomInstanceNode build() {
|
||||
|
@ -7,7 +7,6 @@ import com.oracle.truffle.api.interop.InteropLibrary;
|
||||
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
||||
import com.oracle.truffle.api.library.CachedLibrary;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.Constants;
|
||||
import org.enso.interpreter.dsl.AcceptsError;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.epb.runtime.PolyglotProxy;
|
||||
@ -16,12 +15,12 @@ import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||
import org.enso.interpreter.runtime.number.EnsoBigInteger;
|
||||
import org.enso.interpreter.runtime.type.TypesGen;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "type_of_builtin",
|
||||
description = "Returns the type of a value.")
|
||||
name = "type_of",
|
||||
description = "Returns the type of a value.",
|
||||
autoRegister = false)
|
||||
public abstract class TypeOfNode extends Node {
|
||||
|
||||
public abstract Object execute(@AcceptsError Object value);
|
||||
|
@ -15,7 +15,11 @@ import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
|
||||
@BuiltinMethod(type = "Array", name = "copy", description = "Copies one array to another.")
|
||||
@BuiltinMethod(
|
||||
type = "Array",
|
||||
name = "copy",
|
||||
description = "Copies one array to another.",
|
||||
autoRegister = false)
|
||||
public abstract class CopyNode extends Node {
|
||||
|
||||
static CopyNode build() {
|
||||
|
@ -27,7 +27,8 @@ import org.enso.interpreter.runtime.type.TypesGen;
|
||||
description =
|
||||
"Takes a computation acquiring a resource, a function taking the resource and closing it,"
|
||||
+ " and a function performing arbitrary operations on the resource. Ensures closing"
|
||||
+ " the resource, even if an exception is raised in the computation.")
|
||||
+ " the resource, even if an exception is raised in the computation.",
|
||||
autoRegister = false)
|
||||
public abstract class BracketNode extends Node {
|
||||
|
||||
private @Child ThunkExecutorNode invokeConstructorNode = ThunkExecutorNode.build();
|
||||
|
@ -11,7 +11,8 @@ import org.enso.interpreter.runtime.state.State;
|
||||
@BuiltinMethod(
|
||||
type = "Runtime",
|
||||
name = "allow_input_in",
|
||||
description = "Allows input in the specified scope.")
|
||||
description = "Allows input in the specified scope.",
|
||||
autoRegister = false)
|
||||
public class AllowInputInNode extends Node {
|
||||
private @Child ThunkExecutorNode thunkExecutorNode = ThunkExecutorNode.build();
|
||||
private @Child ExpectStringNode expectStringNode = ExpectStringNode.build();
|
||||
|
@ -11,7 +11,8 @@ import org.enso.interpreter.runtime.state.State;
|
||||
@BuiltinMethod(
|
||||
type = "Runtime",
|
||||
name = "allow_output_in",
|
||||
description = "Allows output in the specified scope.")
|
||||
description = "Allows output in the specified scope.",
|
||||
autoRegister = false)
|
||||
public class AllowOutputInNode extends Node {
|
||||
private @Child ThunkExecutorNode thunkExecutorNode = ThunkExecutorNode.build();
|
||||
private @Child ExpectStringNode expectStringNode = ExpectStringNode.build();
|
||||
|
@ -6,10 +6,14 @@ import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
|
||||
@BuiltinMethod(type = "Runtime", name = "gc", description = "Forces garbage collection")
|
||||
@BuiltinMethod(
|
||||
type = "Runtime",
|
||||
name = "gc",
|
||||
description = "Forces garbage collection",
|
||||
autoRegister = false)
|
||||
public abstract class GCNode extends Node {
|
||||
|
||||
public abstract Object execute(Object self);
|
||||
public abstract Object execute();
|
||||
|
||||
/** @return A new GCNode. */
|
||||
public static GCNode build() {
|
||||
|
@ -9,7 +9,8 @@ import org.enso.interpreter.runtime.error.PanicException;
|
||||
@BuiltinMethod(
|
||||
type = "Runtime",
|
||||
name = "primitive_get_stack_trace",
|
||||
description = "Gets the current execution stacktrace.")
|
||||
description = "Gets the current execution stacktrace.",
|
||||
autoRegister = false)
|
||||
public class GetStackTraceNode extends Node {
|
||||
Array execute() {
|
||||
var exception = new PanicException("Stacktrace", this);
|
||||
|
@ -11,7 +11,8 @@ import org.enso.interpreter.runtime.state.State;
|
||||
@BuiltinMethod(
|
||||
type = "Runtime",
|
||||
name = "no_inline",
|
||||
description = "Runs its argument without the possibility of getting inlined.")
|
||||
description = "Runs its argument without the possibility of getting inlined.",
|
||||
autoRegister = false)
|
||||
public class NoInlineNode extends Node {
|
||||
private @Child ThunkExecutorNode thunkExecutorNode = ThunkExecutorNode.build();
|
||||
|
||||
|
@ -14,7 +14,8 @@ import org.enso.interpreter.runtime.state.State;
|
||||
type = "Runtime",
|
||||
name = "no_inline_with_arg",
|
||||
description =
|
||||
"Runs its first argument applied to the second argument without the possibility of the call or its argument getting inlined.")
|
||||
"Runs its first argument applied to the second argument without the possibility of the call or its argument getting inlined.",
|
||||
autoRegister = false)
|
||||
public class NoInlineWithArgNode extends Node {
|
||||
private @Child InvokeCallableNode invokeCallableNode;
|
||||
|
||||
|
@ -15,7 +15,8 @@ import org.enso.interpreter.runtime.state.State;
|
||||
@BuiltinMethod(
|
||||
type = "State",
|
||||
name = "get",
|
||||
description = "Returns the current value of monadic state.")
|
||||
description = "Returns the current value of monadic state.",
|
||||
autoRegister = false)
|
||||
@ReportPolymorphism
|
||||
public abstract class GetStateNode extends Node {
|
||||
static GetStateNode build() {
|
||||
|
@ -12,7 +12,11 @@ import org.enso.interpreter.runtime.Context;
|
||||
import org.enso.interpreter.runtime.error.PanicException;
|
||||
import org.enso.interpreter.runtime.state.State;
|
||||
|
||||
@BuiltinMethod(type = "State", name = "put", description = "Updates the value of monadic state.")
|
||||
@BuiltinMethod(
|
||||
type = "State",
|
||||
name = "put",
|
||||
description = "Updates the value of monadic state.",
|
||||
autoRegister = false)
|
||||
@ReportPolymorphism
|
||||
public abstract class PutStateNode extends Node {
|
||||
static PutStateNode build() {
|
||||
|
@ -15,7 +15,8 @@ import org.enso.interpreter.runtime.state.State;
|
||||
@BuiltinMethod(
|
||||
type = "State",
|
||||
name = "run",
|
||||
description = "Runs a stateful computation in a local state environment.")
|
||||
description = "Runs a stateful computation in a local state environment.",
|
||||
autoRegister = false)
|
||||
@ReportPolymorphism
|
||||
public abstract class RunStateNode extends Node {
|
||||
static RunStateNode build() {
|
||||
|
@ -10,7 +10,8 @@ import org.enso.interpreter.runtime.data.text.Text;
|
||||
@BuiltinMethod(
|
||||
type = "Prim_Text_Helper",
|
||||
name = "optimize",
|
||||
description = "Forces flattening of a text value, for testing purposes.")
|
||||
description = "Forces flattening of a text value, for testing purposes.",
|
||||
autoRegister = false)
|
||||
public abstract class OptimizeNode extends Node {
|
||||
private @Child ToJavaStringNode toJavaStringNode = ToJavaStringNode.build();
|
||||
|
||||
|
@ -11,7 +11,8 @@ import org.enso.interpreter.runtime.state.State;
|
||||
@BuiltinMethod(
|
||||
type = "Thread",
|
||||
name = "with_interrupt_handler",
|
||||
description = "Runs a computation with a handler for thread interrupts.")
|
||||
description = "Runs a computation with a handler for thread interrupts.",
|
||||
autoRegister = false)
|
||||
public class WithInterruptHandlerNode extends Node {
|
||||
private @Child ThunkExecutorNode actExecutorNode = ThunkExecutorNode.build();
|
||||
private @Child ThunkExecutorNode handlerExecutorNode = ThunkExecutorNode.build();
|
||||
|
@ -7,7 +7,8 @@ import org.enso.interpreter.runtime.callable.atom.Atom;
|
||||
@BuiltinMethod(
|
||||
type = "Unsafe",
|
||||
name = "set_atom_field",
|
||||
description = "Unsafely, in place, sets the value of an atom field by index.")
|
||||
description = "Unsafely, in place, sets the value of an atom field by index.",
|
||||
autoRegister = false)
|
||||
public class SetAtomFieldNode extends Node {
|
||||
Atom execute(Atom atom, long index, Object value) {
|
||||
atom.getFields()[(int) index] = value;
|
||||
|
@ -27,6 +27,7 @@ import org.enso.compiler.core.IR;
|
||||
import org.enso.interpreter.node.callable.dispatch.CallOptimiserNode;
|
||||
import org.enso.interpreter.node.callable.dispatch.LoopingCallOptimiserNode;
|
||||
import org.enso.interpreter.runtime.builtin.Builtins;
|
||||
import org.enso.interpreter.runtime.builtin.BuiltinFunction;
|
||||
import org.enso.interpreter.runtime.callable.CallerInfo;
|
||||
import org.enso.interpreter.runtime.callable.function.Function;
|
||||
import org.enso.interpreter.runtime.data.Array;
|
||||
@ -571,14 +572,14 @@ public final class Module implements TruffleObject {
|
||||
throws ArityException, UnsupportedTypeException {
|
||||
String expr = Types.extractArguments(args, String.class);
|
||||
Builtins builtins = context.getBuiltins();
|
||||
Function eval =
|
||||
BuiltinFunction eval =
|
||||
builtins
|
||||
.getBuiltinFunction(
|
||||
builtins.debug(), Builtins.MethodNames.Debug.EVAL, context.getLanguage())
|
||||
.orElseThrow();
|
||||
CallerInfo callerInfo = new CallerInfo(null, LocalScope.root(), scope);
|
||||
return callOptimiserNode.executeDispatch(
|
||||
eval,
|
||||
eval.getFunction(),
|
||||
callerInfo,
|
||||
context.emptyState(),
|
||||
new Object[] {builtins.debug(), Text.create(expr)});
|
||||
|
@ -0,0 +1,23 @@
|
||||
package org.enso.interpreter.runtime.builtin;
|
||||
|
||||
import org.enso.interpreter.runtime.callable.function.Function;
|
||||
|
||||
/** BuiltinFunction encapsulates information about a builtin runtime function and its metadata. */
|
||||
public class BuiltinFunction {
|
||||
// Note: ideally BuiltinFunction would be a record but there appears to be a bug in frgaal.
|
||||
private Function fun;
|
||||
private boolean autoRegister;
|
||||
|
||||
public BuiltinFunction(Function fun, boolean autoRegister) {
|
||||
this.fun = fun;
|
||||
this.autoRegister = autoRegister;
|
||||
}
|
||||
|
||||
public boolean isAutoRegister() {
|
||||
return this.autoRegister;
|
||||
}
|
||||
|
||||
public Function getFunction() {
|
||||
return this.fun;
|
||||
}
|
||||
}
|
@ -3,12 +3,15 @@ package org.enso.interpreter.runtime.builtin;
|
||||
import com.oracle.truffle.api.CompilerDirectives;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
import org.enso.compiler.Passes;
|
||||
import org.enso.compiler.context.FreshNameSupply;
|
||||
import org.enso.compiler.exception.CompilerError;
|
||||
@ -44,14 +47,13 @@ import java.io.InputStreamReader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** Container class for static predefined atoms, methods, and their containing scope. */
|
||||
public class Builtins {
|
||||
|
||||
private static final List<Constructor<? extends Builtin>> loadedBuiltinConstructors;
|
||||
private static final Map<String, Method> loadedBbuiltinMethods;
|
||||
private static final Map<String, LoadedBuiltinMethod> loadedBbuiltinMethods;
|
||||
|
||||
static {
|
||||
loadedBuiltinConstructors = readBuiltinTypes();
|
||||
@ -70,7 +72,7 @@ public class Builtins {
|
||||
}
|
||||
|
||||
private final Map<Class<? extends Builtin>, Builtin> builtins;
|
||||
private final Map<String, Map<String, Method>> builtinMethodNodes;
|
||||
private final Map<String, Map<String, LoadedBuiltinMethod>> builtinMethodNodes;
|
||||
private final Map<String, Builtin> builtinsByName;
|
||||
|
||||
private final Error error;
|
||||
@ -162,18 +164,17 @@ public class Builtins {
|
||||
for (Builtin builtin : builtins.values()) {
|
||||
var type = builtin.getType();
|
||||
String tpeName = type.getName();
|
||||
Map<String, Method> methods = builtinMethodNodes.get(tpeName);
|
||||
Map<String, LoadedBuiltinMethod> methods = builtinMethodNodes.get(tpeName);
|
||||
if (methods != null) {
|
||||
methods.forEach(
|
||||
(methodName, meth) -> {
|
||||
Optional<Function> fun;
|
||||
try {
|
||||
fun = Optional.ofNullable((Function) meth.invoke(null, language));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fun = Optional.empty();
|
||||
// Register a builtin method iff it is marked as auto-register.
|
||||
// Methods can only register under a type or, if we deal with a static method, it's eigen-type.
|
||||
// Such builtins are available on certain types without importing the whole stdlib, e.g. Any or Number.
|
||||
methods.entrySet().stream().forEach(entry -> {
|
||||
Type tpe = entry.getValue().isAutoRegister ? (!entry.getValue().isStatic() ? type : type.getEigentype()) : null;
|
||||
if (tpe != null) {
|
||||
Optional<BuiltinFunction> fun = entry.getValue().toFunction(language);
|
||||
fun.ifPresent(f -> scope.registerMethod(tpe, entry.getKey(), f.getFunction()));
|
||||
}
|
||||
fun.ifPresent(f -> scope.registerMethod(type, methodName, f));
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -209,14 +210,13 @@ public class Builtins {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of Builtin Types and their instances.
|
||||
* Returns a list of supported builtins.
|
||||
*
|
||||
* <p>Builtin types are marked via @BuiltinType annotation. THe metdata file represents a single
|
||||
* builtin type per row. The format of the row is as follows: <Enso name of the builtin
|
||||
* type>:<Name of the class representing it>:[<field1>,<field2>,...] where the last column gives a
|
||||
* list of optional type's fields.
|
||||
*
|
||||
* @return map of builtin types' classes and their instances
|
||||
*/
|
||||
private static List<Constructor<? extends Builtin>> readBuiltinTypes() {
|
||||
ClassLoader classLoader = Builtins.class.getClassLoader();
|
||||
@ -281,12 +281,12 @@ public class Builtins {
|
||||
* @param scope Builtins scope
|
||||
* @return A map of builtin method nodes per builtin type name
|
||||
*/
|
||||
private Map<String, Map<String, Method>> readBuiltinMethodsMetadata(
|
||||
Map<String, Method> classes, ModuleScope scope) {
|
||||
private Map<String, Map<String, LoadedBuiltinMethod>> readBuiltinMethodsMetadata(
|
||||
Map<String, LoadedBuiltinMethod> classes, ModuleScope scope) {
|
||||
|
||||
Map<String, Map<String, Method>> methodNodes = new HashMap<>();
|
||||
Map<String, Map<String, LoadedBuiltinMethod>> methodNodes = new HashMap<>();
|
||||
classes.forEach(
|
||||
(fullBuiltinName, meth) -> {
|
||||
(fullBuiltinName, builtin) -> {
|
||||
String[] builtinName = fullBuiltinName.split("\\.");
|
||||
if (builtinName.length != 2) {
|
||||
throw new CompilerError("Invalid builtin metadata for " + fullBuiltinName);
|
||||
@ -296,22 +296,22 @@ public class Builtins {
|
||||
Optional.ofNullable(scope.getTypes().get(builtinMethodOwner))
|
||||
.ifPresentOrElse(
|
||||
constr -> {
|
||||
Map<String, Method> atomNodes = methodNodes.get(builtinMethodOwner);
|
||||
Map<String, LoadedBuiltinMethod> atomNodes = methodNodes.get(builtinMethodOwner);
|
||||
if (atomNodes == null) {
|
||||
atomNodes = new HashMap<>();
|
||||
// TODO: move away from String Map once Builtins are gone
|
||||
methodNodes.put(constr.getName(), atomNodes);
|
||||
}
|
||||
atomNodes.put(builtinMethodName, meth);
|
||||
atomNodes.put(builtinMethodName, builtin);
|
||||
},
|
||||
() -> {
|
||||
Map<String, Method> atomNodes = methodNodes.get(builtinMethodOwner);
|
||||
Map<String, LoadedBuiltinMethod> atomNodes = methodNodes.get(builtinMethodOwner);
|
||||
if (atomNodes == null) {
|
||||
atomNodes = new HashMap<>();
|
||||
// TODO: move away from String Map once Builtins are gone
|
||||
methodNodes.put(builtinMethodOwner, atomNodes);
|
||||
}
|
||||
atomNodes.put(builtinMethodName, meth);
|
||||
atomNodes.put(builtinMethodName, builtin);
|
||||
});
|
||||
});
|
||||
return methodNodes;
|
||||
@ -326,7 +326,7 @@ public class Builtins {
|
||||
*
|
||||
* @return A map of builtin method nodes per builtin type name
|
||||
*/
|
||||
private static Map<String, Method> readBuiltinMethodsMethods() {
|
||||
private static Map<String, LoadedBuiltinMethod> readBuiltinMethodsMethods() {
|
||||
ClassLoader classLoader = Builtins.class.getClassLoader();
|
||||
List<String> lines;
|
||||
try (InputStream resource = classLoader.getResourceAsStream(MethodDefinition.META_PATH)) {
|
||||
@ -343,20 +343,23 @@ public class Builtins {
|
||||
.map(
|
||||
line -> {
|
||||
String[] builtinMeta = line.split(":");
|
||||
if (builtinMeta.length != 2) {
|
||||
if (builtinMeta.length != 4) {
|
||||
throw new CompilerError("Invalid builtin metadata in: " + line);
|
||||
}
|
||||
String[] builtinName = builtinMeta[0].split("\\.");
|
||||
if (builtinName.length != 2) {
|
||||
throw new CompilerError("Invalid builtin metadata in : " + line);
|
||||
}
|
||||
boolean isStatic = builtinMeta.length == 3 ? java.lang.Boolean.valueOf(builtinMeta[2]) : false;
|
||||
boolean isAutoRegister = builtinMeta.length == 4 && java.lang.Boolean.valueOf(builtinMeta[3]);
|
||||
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<BuiltinRootNode> clazz =
|
||||
(Class<BuiltinRootNode>) Class.forName(builtinMeta[1]);
|
||||
Method meth = clazz.getMethod("makeFunction", Language.class);
|
||||
// methodNodes.put(builtinMeta[0], meth);
|
||||
return new AbstractMap.SimpleEntry<String, Method>(builtinMeta[0], meth);
|
||||
LoadedBuiltinMethod meta = new LoadedBuiltinMethod(meth, isStatic, isAutoRegister);
|
||||
return new AbstractMap.SimpleEntry<String, LoadedBuiltinMethod>(builtinMeta[0], meta);
|
||||
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
throw new CompilerError("Invalid builtin method " + line);
|
||||
@ -374,21 +377,16 @@ public class Builtins {
|
||||
* @return A non-empty function under the given name, if it exists. An empty value if no such
|
||||
* builtin method was ever registerd
|
||||
*/
|
||||
public Optional<Function> getBuiltinFunction(String type, String methodName, Language language) {
|
||||
public Optional<BuiltinFunction> getBuiltinFunction(String type, String methodName, Language language) {
|
||||
// TODO: move away from String mapping once Builtins is gone
|
||||
Map<String, Method> atomNodes = builtinMethodNodes.get(type);
|
||||
Map<String, LoadedBuiltinMethod> atomNodes = builtinMethodNodes.get(type);
|
||||
if (atomNodes == null) return Optional.empty();
|
||||
Method meth = atomNodes.get(methodName);
|
||||
if (meth == null) return Optional.empty();
|
||||
try {
|
||||
return Optional.ofNullable((Function) meth.invoke(null, language));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
return Optional.empty();
|
||||
}
|
||||
LoadedBuiltinMethod builtin = atomNodes.get(methodName);
|
||||
if (builtin == null) return Optional.empty();
|
||||
return builtin.toFunction(language);
|
||||
}
|
||||
|
||||
public Optional<Function> getBuiltinFunction(Type type, String methodName, Language language) {
|
||||
public Optional<BuiltinFunction> getBuiltinFunction(Type type, String methodName, Language language) {
|
||||
return getBuiltinFunction(type.getName(), methodName, language);
|
||||
}
|
||||
|
||||
@ -611,4 +609,16 @@ public class Builtins {
|
||||
public Type fromTypeSystem(String typeName) {
|
||||
return TypesFromProxy.fromTypeSystem(this, typeName);
|
||||
}
|
||||
|
||||
private record LoadedBuiltinMethod(Method meth, boolean isStatic, boolean isAutoRegister) {
|
||||
Optional<BuiltinFunction> toFunction(Language language) {
|
||||
try {
|
||||
return Optional.ofNullable((Function) meth.invoke(null, language)).map(f-> new BuiltinFunction(f, isAutoRegister));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public final class Array implements TruffleObject {
|
||||
*
|
||||
* @param items the element values
|
||||
*/
|
||||
@Builtin.Method(expandVarargs = 4, description = "Creates an array with given elements.")
|
||||
@Builtin.Method(expandVarargs = 4, description = "Creates an array with given elements.", autoRegister = false)
|
||||
public Array(Object... items) {
|
||||
this.items = items;
|
||||
}
|
||||
@ -36,7 +36,7 @@ public final class Array implements TruffleObject {
|
||||
*
|
||||
* @param size the size of the created array.
|
||||
*/
|
||||
@Builtin.Method(description = "Creates an uninitialized array of a given size.")
|
||||
@Builtin.Method(description = "Creates an uninitialized array of a given size.", autoRegister = false)
|
||||
public Array(long size) {
|
||||
this.items = new Object[(int) size];
|
||||
}
|
||||
@ -80,7 +80,7 @@ public final class Array implements TruffleObject {
|
||||
}
|
||||
|
||||
/** @return an empty array */
|
||||
@Builtin.Method(description = "Creates an empty Array")
|
||||
@Builtin.Method(description = "Creates an empty Array", autoRegister = false)
|
||||
public static Object empty() {
|
||||
return new Array();
|
||||
}
|
||||
|
@ -31,13 +31,13 @@ public final class EnsoDate implements TruffleObject {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Return current Date")
|
||||
@Builtin.Method(description = "Return current Date", autoRegister = false)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static EnsoDate now() {
|
||||
return new EnsoDate(LocalDate.now());
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "internal_parse", description = "Constructs a new Date from text with optional pattern")
|
||||
@Builtin.Method(name = "parse_builtin", description = "Constructs a new Date from text with optional pattern", autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
@Builtin.WrapException(from = DateTimeParseException.class, to = PolyglotError.class)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
@ -51,7 +51,7 @@ public final class EnsoDate implements TruffleObject {
|
||||
}
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "internal_new", description = "Constructs a new Date from a year, month, and day")
|
||||
@Builtin.Method(name = "new_builtin", description = "Constructs a new Date from a year, month, and day", autoRegister = false)
|
||||
@Builtin.WrapException(from = DateTimeException.class, to = PolyglotError.class)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static EnsoDate create(long year, long month, long day) {
|
||||
|
@ -34,12 +34,15 @@ public final class EnsoDateTime implements TruffleObject {
|
||||
this.dateTime = dateTime;
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "epoch_start", description = "Return the Enso start of the Epoch")
|
||||
@Builtin.Method(
|
||||
name = "epoch_start",
|
||||
description = "Return the Enso start of the Epoch",
|
||||
autoRegister = false)
|
||||
public static EnsoDateTime epochStart() {
|
||||
return epochStart;
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Return current DateTime")
|
||||
@Builtin.Method(description = "Return current DateTime", autoRegister = false)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static EnsoDateTime now() {
|
||||
return new EnsoDateTime(ZonedDateTime.now());
|
||||
@ -62,7 +65,8 @@ public final class EnsoDateTime implements TruffleObject {
|
||||
*/
|
||||
@Builtin.Method(
|
||||
name = "parse_builtin",
|
||||
description = "Constructs a new DateTime from text with optional pattern")
|
||||
description = "Constructs a new DateTime from text with optional pattern",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
@Builtin.WrapException(from = DateTimeParseException.class, to = PolyglotError.class)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
@ -78,7 +82,8 @@ public final class EnsoDateTime implements TruffleObject {
|
||||
|
||||
@Builtin.Method(
|
||||
name = "new_builtin",
|
||||
description = "Constructs a new Date from a year, month, and day")
|
||||
description = "Constructs a new Date from a year, month, and day",
|
||||
autoRegister = false)
|
||||
@Builtin.WrapException(from = DateTimeException.class, to = PolyglotError.class)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static EnsoDateTime create(
|
||||
@ -168,16 +173,14 @@ public final class EnsoDateTime implements TruffleObject {
|
||||
}
|
||||
|
||||
@Builtin.Method(
|
||||
name = "to_localtime_builtin",
|
||||
name = "time_of_day",
|
||||
description = "Return the localtime of this date time value.")
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public EnsoTimeOfDay toLocalTime() {
|
||||
return new EnsoTimeOfDay(dateTime.toLocalTime());
|
||||
}
|
||||
|
||||
@Builtin.Method(
|
||||
name = "to_localdate_builtin",
|
||||
description = "Return the localdate of this date time value.")
|
||||
@Builtin.Method(name = "date", description = "Return the localdate of this date time value.")
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public EnsoDate toLocalDate() {
|
||||
return new EnsoDate(dateTime.toLocalDate());
|
||||
@ -189,15 +192,6 @@ public final class EnsoDateTime implements TruffleObject {
|
||||
return new EnsoDateTime(dateTime.withZoneSameInstant(zone.asTimeZone()));
|
||||
}
|
||||
|
||||
@Builtin.Method(
|
||||
name = "to_time_builtin",
|
||||
description = "Combine this day with time to create a point in time.")
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public EnsoDateTime toTime(EnsoTimeOfDay timeOfDay, EnsoTimeZone zone) {
|
||||
return new EnsoDateTime(
|
||||
dateTime.toLocalDate().atTime(timeOfDay.asTime()).atZone(zone.asTimeZone()));
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Return this datetime to the datetime in the provided time zone.")
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public Text toText() {
|
||||
|
@ -1,6 +1,5 @@
|
||||
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;
|
||||
@ -43,7 +42,8 @@ public final class EnsoDuration implements TruffleObject {
|
||||
@Builtin.Method(
|
||||
name = "new_builtin",
|
||||
description =
|
||||
"Constructs a new Duration from hours, minutes, seconds, milliseconds and nanoseconds")
|
||||
"Constructs a new Duration from hours, minutes, seconds, milliseconds and nanoseconds",
|
||||
autoRegister = false)
|
||||
@TruffleBoundary
|
||||
public static EnsoDuration create(
|
||||
long hours, long minutes, long seconds, long milliseconds, long nanoseconds) {
|
||||
@ -59,7 +59,8 @@ public final class EnsoDuration implements TruffleObject {
|
||||
@Builtin.Method(
|
||||
name = "between_builtin",
|
||||
description =
|
||||
"Construct a new Duration that is between the given start date inclusive, and end date exclusive")
|
||||
"Construct a new Duration that is between the given start date inclusive, and end date exclusive",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
@TruffleBoundary
|
||||
public static EnsoDuration between(
|
||||
|
@ -224,7 +224,8 @@ public final class EnsoFile implements TruffleObject {
|
||||
@Builtin.Method(
|
||||
name = "get_file",
|
||||
description =
|
||||
"Takes the text representation of a path and returns a TruffleFile corresponding to it.")
|
||||
"Takes the text representation of a path and returns a TruffleFile corresponding to it.",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static EnsoFile fromString(Context context, String path) {
|
||||
@ -234,7 +235,8 @@ public final class EnsoFile implements TruffleObject {
|
||||
|
||||
@Builtin.Method(
|
||||
name = "get_cwd",
|
||||
description = "A file corresponding to the current working directory.")
|
||||
description = "A file corresponding to the current working directory.",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static EnsoFile currentDirectory(Context context) {
|
||||
@ -242,7 +244,10 @@ public final class EnsoFile implements TruffleObject {
|
||||
return new EnsoFile(file);
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "home", description = "Gets the user's system-defined home directory.")
|
||||
@Builtin.Method(
|
||||
name = "home",
|
||||
description = "Gets the user's system-defined home directory.",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static EnsoFile userHome(Context context) {
|
||||
|
@ -32,7 +32,8 @@ public final class EnsoTimeOfDay implements TruffleObject {
|
||||
|
||||
@Builtin.Method(
|
||||
name = "parse_builtin",
|
||||
description = "Constructs a new DateTime from text with optional pattern")
|
||||
description = "Constructs a new DateTime from text with optional pattern",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
@Builtin.WrapException(from = DateTimeParseException.class, to = PolyglotError.class)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
@ -40,7 +41,10 @@ public final class EnsoTimeOfDay implements TruffleObject {
|
||||
return new EnsoTimeOfDay(LocalTime.parse(text));
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "new_builtin", description = "Constructs a new Time_OF_Day from an hour")
|
||||
@Builtin.Method(
|
||||
name = "new_builtin",
|
||||
description = "Constructs a new Time_OF_Day from an hour",
|
||||
autoRegister = false)
|
||||
@Builtin.WrapException(from = DateTimeException.class, to = PolyglotError.class)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static EnsoTimeOfDay create(long hour, long minute, long second, long nanosecond) {
|
||||
@ -52,7 +56,7 @@ public final class EnsoTimeOfDay implements TruffleObject {
|
||||
Math.toIntExact(nanosecond)));
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Gets a value of hour")
|
||||
@Builtin.Method(description = "Gets a value of hour", autoRegister = false)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static EnsoTimeOfDay now() {
|
||||
return new EnsoTimeOfDay(LocalTime.now());
|
||||
@ -107,7 +111,7 @@ public final class EnsoTimeOfDay implements TruffleObject {
|
||||
}
|
||||
|
||||
@Builtin.Method(
|
||||
name = "to_time_builtin",
|
||||
name = "to_date_time_builtin",
|
||||
description = "Combine this time of day with a date to create a point in time.")
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public EnsoDateTime toTime(EnsoDate date, EnsoTimeZone zone) {
|
||||
|
@ -15,7 +15,6 @@ import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||
import java.time.DateTimeException;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.zone.ZoneRulesException;
|
||||
|
||||
@ExportLibrary(InteropLibrary.class)
|
||||
@ -34,7 +33,10 @@ public final class EnsoTimeZone implements TruffleObject {
|
||||
return Text.create(this.zone.getId());
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "parse_builtin", description = "Parse the ID producing a Time_Zone.")
|
||||
@Builtin.Method(
|
||||
name = "parse_builtin",
|
||||
description = "Parse the ID producing a Time_Zone.",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
@Builtin.WrapException(from = ZoneRulesException.class, to = PolyglotError.class)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
@ -45,7 +47,8 @@ public final class EnsoTimeZone implements TruffleObject {
|
||||
@Builtin.Method(
|
||||
name = "new_builtin",
|
||||
description =
|
||||
"Obtains an instance of `Time_Zone` using an offset in hours, minutes and seconds from the UTC zone.")
|
||||
"Obtains an instance of `Time_Zone` using an offset in hours, minutes and seconds from the UTC zone.",
|
||||
autoRegister = false)
|
||||
@Builtin.WrapException(from = DateTimeException.class, to = PolyglotError.class)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static EnsoTimeZone create(long hours, long minutes, long seconds) {
|
||||
@ -54,7 +57,10 @@ public final class EnsoTimeZone implements TruffleObject {
|
||||
Math.toIntExact(hours), Math.toIntExact(minutes), Math.toIntExact(seconds)));
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "system", description = "The system default timezone.")
|
||||
@Builtin.Method(
|
||||
name = "system",
|
||||
description = "The system default timezone.",
|
||||
autoRegister = false)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static EnsoTimeZone system() {
|
||||
return new EnsoTimeZone(ZoneId.systemDefault());
|
||||
|
@ -19,7 +19,7 @@ public final class Ref implements TruffleObject {
|
||||
*
|
||||
* @param value the initial value to store in the reference.
|
||||
*/
|
||||
@Builtin.Method(description = "Creates a new Ref")
|
||||
@Builtin.Method(description = "Creates a new Ref", autoRegister = false)
|
||||
public Ref(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
@ -37,8 +37,9 @@ public final class Vector implements TruffleObject {
|
||||
}
|
||||
|
||||
@Builtin.Method(
|
||||
name = "new_builtin",
|
||||
description = "Creates new Vector with given length and provided elements.")
|
||||
name = "new",
|
||||
description = "Creates new Vector with given length and provided elements.",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
public static Object newFromFunction(long length, Function fun, InteropLibrary interop) {
|
||||
Object[] target = new Object[Math.toIntExact(length)];
|
||||
|
@ -53,7 +53,8 @@ public final class Warning implements TruffleObject {
|
||||
|
||||
@Builtin.Method(
|
||||
name = "create",
|
||||
description = "Creates a new instance of the primitive warning value.")
|
||||
description = "Creates a new instance of the primitive warning value.",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
public static Warning create(Context ctx, Object payload, Object origin) {
|
||||
return new Warning(payload, origin, ctx.clockTick());
|
||||
@ -67,7 +68,8 @@ public final class Warning implements TruffleObject {
|
||||
|
||||
@Builtin.Method(
|
||||
name = "attach_with_stacktrace",
|
||||
description = "Attaches the given warning to the value.")
|
||||
description = "Attaches the given warning to the value.",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
public static WithWarnings attach(
|
||||
Context ctx, WithWarnings value, Object warning, Object origin) {
|
||||
@ -76,7 +78,8 @@ public final class Warning implements TruffleObject {
|
||||
|
||||
@Builtin.Method(
|
||||
name = "attach_with_stacktrace",
|
||||
description = "Attaches the given warning to the value.")
|
||||
description = "Attaches the given warning to the value.",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize(fallback = true)
|
||||
public static WithWarnings attach(Context ctx, Object value, Object warning, Object origin) {
|
||||
return new WithWarnings(value, new Warning(warning, origin, ctx.clockTick()));
|
||||
@ -84,7 +87,8 @@ public final class Warning implements TruffleObject {
|
||||
|
||||
@Builtin.Method(
|
||||
name = "get_all_array",
|
||||
description = "Gets all the warnings associated with the value.")
|
||||
description = "Gets all the warnings associated with the value.",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static Array getAll(WithWarnings value) {
|
||||
@ -97,7 +101,8 @@ public final class Warning implements TruffleObject {
|
||||
|
||||
@Builtin.Method(
|
||||
name = "get_all_array",
|
||||
description = "Gets all the warnings associated with the value.")
|
||||
description = "Gets all the warnings associated with the value.",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize(fallback = true)
|
||||
public static Array getAll(Object value) {
|
||||
return new Array();
|
||||
@ -105,7 +110,8 @@ public final class Warning implements TruffleObject {
|
||||
|
||||
@Builtin.Method(
|
||||
name = "set_array",
|
||||
description = "Gets all the warnings associated with the value.")
|
||||
description = "Gets all the warnings associated with the value.",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize
|
||||
public static Object set(WithWarnings value, Object warnings, InteropLibrary interop) {
|
||||
return setGeneric(value.getValue(), interop, warnings);
|
||||
@ -113,7 +119,8 @@ public final class Warning implements TruffleObject {
|
||||
|
||||
@Builtin.Method(
|
||||
name = "set_array",
|
||||
description = "Gets all the warnings associated with the value.")
|
||||
description = "Gets all the warnings associated with the value.",
|
||||
autoRegister = false)
|
||||
@Builtin.Specialize(fallback = true)
|
||||
public static Object set(Object value, Object warnings, InteropLibrary interop) {
|
||||
return setGeneric(value, interop, warnings);
|
||||
|
@ -22,7 +22,7 @@ public class System {
|
||||
private static final Text WINDOWS = Text.create("windows");
|
||||
private static final Text UNKNOWN = Text.create("unknown");
|
||||
|
||||
@Builtin.Method(description = "Get the type of operating system.")
|
||||
@Builtin.Method(description = "Get the type of operating system.", autoRegister = false)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static Text os() {
|
||||
if (SystemUtils.IS_OS_LINUX) return LINUX;
|
||||
@ -31,26 +31,30 @@ public class System {
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Check if the operating system is UNIX.")
|
||||
@Builtin.Method(description = "Check if the operating system is UNIX.", autoRegister = false)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static Boolean is_unix() {
|
||||
return SystemUtils.IS_OS_UNIX;
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Gets the nanosecond resolution system time.")
|
||||
@Builtin.Method(description = "Gets the nanosecond resolution system time.", autoRegister = false)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static long nanoTime() {
|
||||
return java.lang.System.nanoTime();
|
||||
}
|
||||
|
||||
@Builtin.Method(description = "Exits the process, returning the provided code.")
|
||||
@Builtin.Method(
|
||||
description = "Exits the process, returning the provided code.",
|
||||
autoRegister = false)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public static void exit(long code) {
|
||||
java.lang.System.exit((int) code);
|
||||
}
|
||||
|
||||
@Builtin.Specialize
|
||||
@Builtin.Method(description = "Create a system process, returning the exit code.")
|
||||
@Builtin.Method(
|
||||
description = "Create a system process, returning the exit code.",
|
||||
autoRegister = false)
|
||||
@Builtin.WrapException(from = IOException.class, to = PanicException.class)
|
||||
@Builtin.WrapException(from = InterruptedException.class, to = PanicException.class)
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
|
@ -331,8 +331,10 @@ class IrToTruffle(
|
||||
}
|
||||
|
||||
consOpt.foreach { cons =>
|
||||
val fullMethodDefName =
|
||||
cons.getName ++ Constants.SCOPE_SEPARATOR ++ methodDef.methodName.name
|
||||
val expressionProcessor = new ExpressionProcessor(
|
||||
cons.getName ++ Constants.SCOPE_SEPARATOR ++ methodDef.methodName.name,
|
||||
fullMethodDefName,
|
||||
scopeInfo.graph,
|
||||
scopeInfo.graph.rootScope,
|
||||
dataflowInfo
|
||||
@ -375,7 +377,11 @@ class IrToTruffle(
|
||||
) Right(None)
|
||||
else Left(l)
|
||||
)
|
||||
.map(_.filterNot(_ => cons.isBuiltin))
|
||||
.map(fOpt =>
|
||||
// Register builtin iff it has not been automatically registered at an early stage
|
||||
// of builtins initialization.
|
||||
fOpt.filter(m => !m.isAutoRegister()).map(m => m.getFunction)
|
||||
)
|
||||
case fn: IR.Function =>
|
||||
val bodyBuilder =
|
||||
new expressionProcessor.BuildFunctionBody(
|
||||
|
@ -16,6 +16,7 @@ class PolyglotTest extends InterpreterTest {
|
||||
"allow calling methods on static objects" in {
|
||||
val code =
|
||||
"""from Standard.Base import all
|
||||
|import Standard.Base.Data.Array
|
||||
|
|
||||
|main =
|
||||
| class = Java.lookup_class "org.enso.example.TestClass"
|
||||
@ -60,6 +61,7 @@ class PolyglotTest extends InterpreterTest {
|
||||
"allow instantiating objects and calling methods on them" in {
|
||||
val code =
|
||||
"""from Standard.Base import all
|
||||
|import Standard.Base.Data.Array
|
||||
|
|
||||
|main =
|
||||
| class = Java.lookup_class "org.enso.example.TestClass"
|
||||
@ -72,6 +74,7 @@ class PolyglotTest extends InterpreterTest {
|
||||
"allow listing available members of an object" in {
|
||||
val code =
|
||||
"""from Standard.Base import all
|
||||
|import Standard.Base.Data.Array
|
||||
|
|
||||
|main =
|
||||
| class = Java.lookup_class "org.enso.example.TestClass"
|
||||
@ -106,7 +109,7 @@ class PolyglotTest extends InterpreterTest {
|
||||
consumeOut shouldEqual List("0", "[]")
|
||||
}
|
||||
|
||||
"match on Polyglot type when imported everything from stdlib" in {
|
||||
"fail to match on Polyglot symbol when imported everything from stdlib" in {
|
||||
val code =
|
||||
"""from Standard.Base import all
|
||||
|polyglot java import java.util.Random
|
||||
@ -119,7 +122,7 @@ class PolyglotTest extends InterpreterTest {
|
||||
|""".stripMargin
|
||||
eval(code)
|
||||
val count :: Nil = consumeOut
|
||||
count shouldEqual "OK"
|
||||
count shouldEqual "FAIL"
|
||||
}
|
||||
|
||||
"fail to match on Polyglot type when explicitly importing everything from Polyglot module" in {
|
||||
|
@ -153,6 +153,13 @@ public @interface Builtin {
|
||||
* @return number of desired expansions for vararg parameter.
|
||||
*/
|
||||
int expandVarargs() default 0;
|
||||
|
||||
/**
|
||||
* `autoRegister` property indicates whether the builtin method should be automatically
|
||||
* registered with the underlying type. By default every builtin method is registered with a
|
||||
* type. Auto-registered methods do not have to be declared explicitly.
|
||||
*/
|
||||
boolean autoRegister() default true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,4 +20,7 @@ public @interface BuiltinMethod {
|
||||
|
||||
/** @return a list of aliases (names) of this method */
|
||||
String aliases() default "";
|
||||
|
||||
/** @return whether a method should be registered automatically with a type */
|
||||
boolean autoRegister() default true;
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ public abstract class BuiltinsMetadataProcessor<T extends BuiltinsMetadataProces
|
||||
|
||||
/**
|
||||
* The method called at the end of the round of annotation processing. It allows to write any
|
||||
* collected metadata to a related resoource (see {@link
|
||||
* collected metadata to a related resources (see {@link
|
||||
* BuiltinsMetadataProcessor#metadataPath()}).
|
||||
*
|
||||
* @param writer a writer to the metadata resource
|
||||
|
@ -169,7 +169,8 @@ public class BuiltinsProcessor extends AbstractProcessor {
|
||||
processingEnv,
|
||||
methodName,
|
||||
annotation.description(),
|
||||
method.getSimpleName().toString());
|
||||
method.getSimpleName().toString(),
|
||||
annotation.autoRegister());
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
@ -222,7 +223,8 @@ public class BuiltinsProcessor extends AbstractProcessor {
|
||||
processingEnv,
|
||||
builtinMethodName,
|
||||
annotation.description(),
|
||||
method.getSimpleName().toString());
|
||||
method.getSimpleName().toString(),
|
||||
annotation.autoRegister());
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -235,7 +237,8 @@ public class BuiltinsProcessor extends AbstractProcessor {
|
||||
processingEnv,
|
||||
builtinMethodName,
|
||||
annotation.description(),
|
||||
method.getSimpleName().toString());
|
||||
method.getSimpleName().toString(),
|
||||
annotation.autoRegister());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -23,6 +23,7 @@ import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import org.enso.interpreter.dsl.model.MethodDefinition;
|
||||
import org.enso.interpreter.dsl.model.MethodDefinition.ArgumentDefinition;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
@ -35,7 +36,7 @@ import org.openide.util.lookup.ServiceProvider;
|
||||
@ServiceProvider(service = Processor.class)
|
||||
public class MethodProcessor extends BuiltinsMetadataProcessor<MethodProcessor.MethodMetadataEntry> {
|
||||
|
||||
private final Map<Filer, Map<String, String>> builtinMethods = new HashMap<>();
|
||||
private final Map<Filer, Map<String, String[]>> builtinMethods = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Processes annotated elements, generating code for each of them. The method also records
|
||||
@ -108,10 +109,10 @@ public class MethodProcessor extends BuiltinsMetadataProcessor<MethodProcessor.M
|
||||
return;
|
||||
}
|
||||
String fullClassName = def.getPackageName() + "." + def.getClassName();
|
||||
registerBuiltinMethod(processingEnv.getFiler(), def.getDeclaredName(), fullClassName);
|
||||
registerBuiltinMethod(processingEnv.getFiler(), def.getDeclaredName(), fullClassName, def.isStatic(), def.isAutoRegister());
|
||||
if (def.hasAliases()) {
|
||||
for (String alias : def.aliases()) {
|
||||
registerBuiltinMethod(processingEnv.getFiler(), alias, fullClassName);
|
||||
registerBuiltinMethod(processingEnv.getFiler(), alias, fullClassName, def.isStatic(), def.isAutoRegister());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -463,8 +464,8 @@ public class MethodProcessor extends BuiltinsMetadataProcessor<MethodProcessor.M
|
||||
*/
|
||||
protected void storeMetadata(Writer writer, Map<String, MethodMetadataEntry> pastEntries) throws IOException {
|
||||
for (Filer f : builtinMethods.keySet()) {
|
||||
for (Map.Entry<String, String> entry : builtinMethods.get(f).entrySet()) {
|
||||
writer.append(entry.getKey() + ":" + entry.getValue() + "\n");
|
||||
for (Map.Entry<String, String[]> entry : builtinMethods.get(f).entrySet()) {
|
||||
writer.append(entry.getKey() + ":" + String.join(":", Arrays.asList(entry.getValue())) + "\n");
|
||||
if (pastEntries.containsKey(entry.getKey())) {
|
||||
pastEntries.remove(entry.getKey());
|
||||
}
|
||||
@ -472,13 +473,13 @@ public class MethodProcessor extends BuiltinsMetadataProcessor<MethodProcessor.M
|
||||
}
|
||||
}
|
||||
|
||||
protected void registerBuiltinMethod(Filer f, String name, String clazzName) {
|
||||
Map<String, String> methods = builtinMethods.get(f);
|
||||
protected void registerBuiltinMethod(Filer f, String name, String clazzName, boolean isStatic, boolean isAutoRegister) {
|
||||
Map<String, String[]> methods = builtinMethods.get(f);
|
||||
if (methods == null) {
|
||||
methods = new HashMap<>();
|
||||
builtinMethods.put(f, methods);
|
||||
}
|
||||
methods.put(name, clazzName);
|
||||
methods.put(name, new String[] { clazzName, String.valueOf(isStatic), String.valueOf(isAutoRegister) });
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -511,11 +512,11 @@ public class MethodProcessor extends BuiltinsMetadataProcessor<MethodProcessor.M
|
||||
return SourceVersion.latest();
|
||||
}
|
||||
|
||||
public record MethodMetadataEntry(String fullEnsoName, String clazzName) implements MetadataEntry {
|
||||
public record MethodMetadataEntry(String fullEnsoName, String clazzName, boolean isStatic, boolean isAutoRegister) implements MetadataEntry {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fullEnsoName + ":" + clazzName;
|
||||
return fullEnsoName + ":" + clazzName + ":" + isStatic + ":" + isAutoRegister;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -527,8 +528,8 @@ public class MethodProcessor extends BuiltinsMetadataProcessor<MethodProcessor.M
|
||||
@Override
|
||||
protected MethodMetadataEntry toMetadataEntry(String line) {
|
||||
String[] elements = line.split(":");
|
||||
if (elements.length != 2) throw new RuntimeException("invalid builtin metadata entry: " + line);
|
||||
return new MethodMetadataEntry(elements[0], elements[1]);
|
||||
if (elements.length != 4) throw new RuntimeException("invalid builtin metadata entry: " + line);
|
||||
return new MethodMetadataEntry(elements[0], elements[1], Boolean.valueOf(elements[2]), Boolean.valueOf(elements[3]));
|
||||
}
|
||||
|
||||
private static final String DATAFLOW_ERROR_PROFILE = "IsDataflowErrorConditionProfile";
|
||||
|
@ -9,7 +9,6 @@ import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.enso.interpreter.dsl.Builtin;
|
||||
|
||||
@ -39,7 +38,8 @@ public abstract class MethodNodeClassGenerator {
|
||||
ProcessingEnvironment processingEnv,
|
||||
String methodName,
|
||||
String description,
|
||||
String ownerMethodName)
|
||||
String ownerMethodName,
|
||||
boolean isAutoRegister)
|
||||
throws IOException {
|
||||
JavaFileObject gen =
|
||||
processingEnv.getFiler().createSourceFile(builtinNode.jvmFriendlyFullyQualifiedName());
|
||||
@ -54,6 +54,10 @@ public abstract class MethodNodeClassGenerator {
|
||||
}
|
||||
out.println("import " + ownerClazz.fullyQualifiedName() + ";");
|
||||
out.println();
|
||||
String moduleOwnerInfo = "";
|
||||
if (!isAutoRegister) {
|
||||
moduleOwnerInfo = ", autoRegister = " + isAutoRegister;
|
||||
}
|
||||
out.println(
|
||||
"@BuiltinMethod(type = \""
|
||||
+ ensoTypeName
|
||||
@ -61,7 +65,9 @@ public abstract class MethodNodeClassGenerator {
|
||||
+ ensoMethodName
|
||||
+ "\", description = \"\"\"\n"
|
||||
+ description
|
||||
+ "\"\"\")");
|
||||
+ "\"\"\""
|
||||
+ moduleOwnerInfo
|
||||
+ ")");
|
||||
if (isAbstract()) {
|
||||
out.println("public abstract class " + builtinNode.jvmFriendlyName() + " extends Node {");
|
||||
out.println();
|
||||
|
@ -8,7 +8,6 @@ import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.tools.Diagnostic;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** A domain-specific representation of a builtin method. */
|
||||
public class MethodDefinition {
|
||||
@ -199,6 +198,18 @@ public class MethodDefinition {
|
||||
return constructorExpression;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return arguments.stream()
|
||||
.filter(arg -> arg.isSelf())
|
||||
.findFirst()
|
||||
.map(arg -> arg.isSyntheticSelf())
|
||||
.orElseGet(() -> false);
|
||||
}
|
||||
|
||||
public boolean isAutoRegister() {
|
||||
return annotation.autoRegister();
|
||||
}
|
||||
|
||||
public interface ArgumentDefinition {
|
||||
|
||||
boolean validate(ProcessingEnvironment processingEnvironment);
|
||||
@ -242,6 +253,8 @@ public class MethodDefinition {
|
||||
|
||||
boolean isSelf();
|
||||
|
||||
boolean isSyntheticSelf();
|
||||
|
||||
boolean shouldCheckErrors();
|
||||
|
||||
boolean shouldCheckWarnings();
|
||||
@ -332,6 +345,11 @@ public class MethodDefinition {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSyntheticSelf() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCheckErrors() {
|
||||
return false;
|
||||
@ -518,6 +536,11 @@ public class MethodDefinition {
|
||||
return name.equals(SELF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSyntheticSelf() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldCheckErrors() {
|
||||
return isPositional() && !isSelf() && !acceptsError();
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Data.Array
|
||||
|
||||
from Standard.Test import Test, Test_Suite
|
||||
|
||||
polyglot java import java.util.LinkedHashSet
|
||||
|
||||
Array.method self = 0
|
||||
Array.Array.method self = 0
|
||||
|
||||
## Returns an array with the same contents as the given vector, surely backed by
|
||||
the Enso Array primitive.
|
||||
|
@ -427,7 +427,7 @@ js_set_zone local_datetime =
|
||||
zone = Time_Zone.utc
|
||||
datetime_with_tz = local_datetime.at_zone zone
|
||||
diff = Duration.between datetime_with_tz local_datetime (timezone_aware=False)
|
||||
(datetime_with_tz + diff).to_localdate_builtin
|
||||
(datetime_with_tz + diff).date
|
||||
|
||||
js_date year month=1 day=1 =
|
||||
Panic.catch Any (js_set_zone (js_date_impl year month day)) (err -> Error.throw (Time_Error_Data err.payload.cause))
|
||||
|
@ -101,10 +101,10 @@ spec = Test.group "Pattern Matches" <|
|
||||
Test.specify "should be able to match on the Polyglot type" <|
|
||||
random_gen = Random.new
|
||||
case random_gen of
|
||||
Polyglot -> Nothing
|
||||
Polyglot.Polyglot -> Nothing
|
||||
_ -> Test.fail "Expected a polyglot object to match."
|
||||
case Polyglot of
|
||||
Polyglot -> Nothing
|
||||
case Polyglot.Polyglot of
|
||||
Polyglot.Polyglot -> Nothing
|
||||
_ -> Test.fail "Expected the Polyglot constructor to match."
|
||||
Test.specify "should be able to match on the Any type" <|
|
||||
value_1 = 1.23143
|
||||
|
@ -79,7 +79,7 @@ spec = Test.group "Meta-Value Manipulation" <|
|
||||
1.0.is_a Text . should_be_false
|
||||
|
||||
random_gen = Random.new
|
||||
Meta.is_a random_gen Polyglot . should_be_true
|
||||
Meta.is_a random_gen Polyglot.Polyglot . should_be_true
|
||||
Meta.is_a random_gen Integer . should_be_false
|
||||
|
||||
(My_Type.Value 1 "foo" Nothing).is_a My_Type.Value . should_be_true
|
||||
|
@ -1,2 +1,5 @@
|
||||
@Builtin_Type
|
||||
type Any
|
||||
catch_primitive handler = @Builtin_Method "Any.catch_primitive"
|
||||
to_text self = @Builtin_Method "Any.to_text"
|
||||
to_display_text self = @Builtin_Method "Any.to_display_text"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user