mirror of
https://github.com/enso-org/enso.git
synced 2025-01-03 09:32:59 +03:00
Run whole test/Base_Tests in native image runner (#10296)
This commit is contained in:
parent
b5641aa3bd
commit
fe2cf49568
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -33,7 +33,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"name": "Launch Native Image",
|
"name": "Launch Native Image",
|
||||||
"nativeImagePath": "${workspaceFolder}/runner",
|
"nativeImagePath": "${workspaceFolder}/runner",
|
||||||
"args": "--help"
|
"args": "--run ${file}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
14
build.sbt
14
build.sbt
@ -2549,8 +2549,10 @@ lazy val `engine-runner` = project
|
|||||||
if (smallJdkDirectory.exists()) {
|
if (smallJdkDirectory.exists()) {
|
||||||
IO.delete(smallJdkDirectory)
|
IO.delete(smallJdkDirectory)
|
||||||
}
|
}
|
||||||
val JS_MODULES =
|
val NI_MODULES =
|
||||||
"org.graalvm.nativeimage,org.graalvm.nativeimage.builder,org.graalvm.nativeimage.base,org.graalvm.nativeimage.driver,org.graalvm.nativeimage.librarysupport,org.graalvm.nativeimage.objectfile,org.graalvm.nativeimage.pointsto,com.oracle.graal.graal_enterprise,com.oracle.svm.svm_enterprise,jdk.compiler.graal,jdk.httpserver,java.naming,java.net.http"
|
"org.graalvm.nativeimage,org.graalvm.nativeimage.builder,org.graalvm.nativeimage.base,org.graalvm.nativeimage.driver,org.graalvm.nativeimage.librarysupport,org.graalvm.nativeimage.objectfile,org.graalvm.nativeimage.pointsto,com.oracle.graal.graal_enterprise,com.oracle.svm.svm_enterprise"
|
||||||
|
val JDK_MODULES =
|
||||||
|
"jdk.localedata,jdk.compiler.graal,jdk.httpserver,java.naming,java.net.http"
|
||||||
val DEBUG_MODULES = "jdk.jdwp.agent"
|
val DEBUG_MODULES = "jdk.jdwp.agent"
|
||||||
val PYTHON_MODULES = "jdk.security.auth,java.naming"
|
val PYTHON_MODULES = "jdk.security.auth,java.naming"
|
||||||
|
|
||||||
@ -2578,7 +2580,7 @@ lazy val `engine-runner` = project
|
|||||||
}
|
}
|
||||||
|
|
||||||
val exec =
|
val exec =
|
||||||
s"$jlink --module-path ${modules.mkString(":")} --output $smallJdkDirectory --add-modules $JS_MODULES,$DEBUG_MODULES,$PYTHON_MODULES"
|
s"$jlink --module-path ${modules.mkString(":")} --output $smallJdkDirectory --add-modules $NI_MODULES,$JDK_MODULES,$DEBUG_MODULES,$PYTHON_MODULES"
|
||||||
val exitCode = scala.sys.process.Process(exec).!
|
val exitCode = scala.sys.process.Process(exec).!
|
||||||
|
|
||||||
if (exitCode != 0) {
|
if (exitCode != 0) {
|
||||||
@ -2610,6 +2612,9 @@ lazy val `engine-runner` = project
|
|||||||
additionalOptions = Seq(
|
additionalOptions = Seq(
|
||||||
"-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog",
|
"-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog",
|
||||||
"-H:IncludeResources=.*Main.enso$",
|
"-H:IncludeResources=.*Main.enso$",
|
||||||
|
"-H:+AddAllCharsets",
|
||||||
|
"-H:+IncludeAllLocales",
|
||||||
|
"-ea",
|
||||||
// useful perf & debug switches:
|
// useful perf & debug switches:
|
||||||
// "-g",
|
// "-g",
|
||||||
// "-H:+SourceLevelDebug",
|
// "-H:+SourceLevelDebug",
|
||||||
@ -2660,6 +2665,7 @@ lazy val `engine-runner` = project
|
|||||||
.dependsOn(`logging-service`)
|
.dependsOn(`logging-service`)
|
||||||
.dependsOn(`logging-service-logback` % Runtime)
|
.dependsOn(`logging-service-logback` % Runtime)
|
||||||
.dependsOn(`polyglot-api`)
|
.dependsOn(`polyglot-api`)
|
||||||
|
.dependsOn(`enso-test-java-helpers`)
|
||||||
|
|
||||||
lazy val buildSmallJdk =
|
lazy val buildSmallJdk =
|
||||||
taskKey[File]("Build a minimal JDK used for native image generation")
|
taskKey[File]("Build a minimal JDK used for native image generation")
|
||||||
@ -3567,7 +3573,7 @@ ThisBuild / buildEngineDistributionNoIndex := {
|
|||||||
lazy val runEngineDistribution =
|
lazy val runEngineDistribution =
|
||||||
inputKey[Unit]("Run or --debug the engine distribution with arguments")
|
inputKey[Unit]("Run or --debug the engine distribution with arguments")
|
||||||
runEngineDistribution := {
|
runEngineDistribution := {
|
||||||
buildEngineDistribution.value
|
buildEngineDistributionNoIndex.value
|
||||||
val args: Seq[String] = spaceDelimited("<arg>").parsed
|
val args: Seq[String] = spaceDelimited("<arg>").parsed
|
||||||
DistributionPackage.runEnginePackage(
|
DistributionPackage.runEnginePackage(
|
||||||
engineDistributionRoot.value,
|
engineDistributionRoot.value,
|
||||||
|
@ -630,28 +630,12 @@ pub async fn runner_sanity_test(
|
|||||||
repo_root: &crate::paths::generated::RepoRoot,
|
repo_root: &crate::paths::generated::RepoRoot,
|
||||||
enso_java: Option<&str>,
|
enso_java: Option<&str>,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
let factorial_input = "6";
|
|
||||||
let factorial_expected_output = "720";
|
|
||||||
let engine_package = repo_root.built_distribution.enso_engine_triple.engine_package.as_path();
|
let engine_package = repo_root.built_distribution.enso_engine_triple.engine_package.as_path();
|
||||||
// The engine package is necessary for running the native runner.
|
// The engine package is necessary for running the native runner.
|
||||||
ide_ci::fs::tokio::require_exist(engine_package).await?;
|
ide_ci::fs::tokio::require_exist(engine_package).await?;
|
||||||
let output = Command::new(&repo_root.runner)
|
|
||||||
.args([
|
|
||||||
"--run",
|
|
||||||
repo_root.engine.runner.src.test.resources.factorial_enso.as_str(),
|
|
||||||
factorial_input,
|
|
||||||
])
|
|
||||||
.set_env_opt(ENSO_JAVA, enso_java)?
|
|
||||||
.set_env(ENSO_DATA_DIRECTORY, engine_package)?
|
|
||||||
.run_stdout()
|
|
||||||
.await?;
|
|
||||||
ensure!(
|
|
||||||
output.contains(factorial_expected_output),
|
|
||||||
"Native runner output does not contain expected result '{factorial_expected_output}'. Output:\n{output}",
|
|
||||||
);
|
|
||||||
if enso_java.is_none() {
|
if enso_java.is_none() {
|
||||||
let test_base = Command::new(&repo_root.runner)
|
let test_base = Command::new(&repo_root.runner)
|
||||||
.args(["--run", repo_root.test.join("Base_Tests").as_str(), "^Text"])
|
.args(["--run", repo_root.test.join("Base_Tests").as_str()])
|
||||||
.set_env_opt(ENSO_JAVA, enso_java)?
|
.set_env_opt(ENSO_JAVA, enso_java)?
|
||||||
.set_env(ENSO_DATA_DIRECTORY, engine_package)?
|
.set_env(ENSO_DATA_DIRECTORY, engine_package)?
|
||||||
.run_stdout()
|
.run_stdout()
|
||||||
|
@ -4,6 +4,8 @@ import project.Errors.Encoding_Error.Encoding_Error
|
|||||||
from project.Data.Text.Extensions import all
|
from project.Data.Text.Extensions import all
|
||||||
|
|
||||||
polyglot java import java.util.Base64
|
polyglot java import java.util.Base64
|
||||||
|
polyglot java import java.util.Base64.Decoder
|
||||||
|
polyglot java import java.util.Base64.Encoder
|
||||||
|
|
||||||
## A helper utility for handling base64 encoding.
|
## A helper utility for handling base64 encoding.
|
||||||
type Base_64
|
type Base_64
|
||||||
|
@ -30,6 +30,7 @@ from project.Data.Text.Extensions import all
|
|||||||
from project.Metadata.Choice import Option
|
from project.Metadata.Choice import Option
|
||||||
from project.Metadata.Widget import Single_Choice
|
from project.Metadata.Widget import Single_Choice
|
||||||
|
|
||||||
|
polyglot java import com.fasterxml.jackson.core.JsonLocation
|
||||||
polyglot java import com.fasterxml.jackson.core.JsonProcessingException
|
polyglot java import com.fasterxml.jackson.core.JsonProcessingException
|
||||||
polyglot java import com.fasterxml.jackson.databind.JsonNode
|
polyglot java import com.fasterxml.jackson.databind.JsonNode
|
||||||
polyglot java import com.fasterxml.jackson.databind.node.ArrayNode
|
polyglot java import com.fasterxml.jackson.databind.node.ArrayNode
|
||||||
|
@ -9,6 +9,7 @@ import project.Nothing.Nothing
|
|||||||
import project.Panic.Panic
|
import project.Panic.Panic
|
||||||
|
|
||||||
polyglot java import org.enso.base.statistics.FitError
|
polyglot java import org.enso.base.statistics.FitError
|
||||||
|
polyglot java import org.enso.base.statistics.LinearModel
|
||||||
polyglot java import org.enso.base.statistics.Regression
|
polyglot java import org.enso.base.statistics.Regression
|
||||||
|
|
||||||
type Model
|
type Model
|
||||||
|
@ -544,7 +544,7 @@ Text.replace self term:(Text | Regex) replacement:Text (case_sensitivity:Case_Se
|
|||||||
Applies the specified cleansings to the text.
|
Applies the specified cleansings to the text.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
- remove: A vector of the named patterns to cleanse from the text. The named patterns are
|
- remove: A vector of the named patterns to cleanse from the text. The named patterns are
|
||||||
applied in the order they are provided. The same named pattern can be used multiple
|
applied in the order they are provided. The same named pattern can be used multiple
|
||||||
times. The named patterns are:
|
times. The named patterns are:
|
||||||
- ..Leading_Whitespace: Removes all whitespace from the start of the string.
|
- ..Leading_Whitespace: Removes all whitespace from the start of the string.
|
||||||
|
@ -34,6 +34,7 @@ polyglot java import java.time.DateTimeException
|
|||||||
polyglot java import java.time.temporal.ChronoField
|
polyglot java import java.time.temporal.ChronoField
|
||||||
polyglot java import java.time.temporal.IsoFields
|
polyglot java import java.time.temporal.IsoFields
|
||||||
polyglot java import org.enso.base.Time_Utils
|
polyglot java import org.enso.base.Time_Utils
|
||||||
|
polyglot java import org.enso.base.Time_Utils.AdjustOp
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
Constructs a new Date from a year, month, and day.
|
Constructs a new Date from a year, month, and day.
|
||||||
|
@ -11,7 +11,10 @@ polyglot java import java.time.temporal.TemporalAdjuster
|
|||||||
polyglot java import java.time.temporal.TemporalAdjusters
|
polyglot java import java.time.temporal.TemporalAdjusters
|
||||||
polyglot java import java.time.temporal.TemporalUnit
|
polyglot java import java.time.temporal.TemporalUnit
|
||||||
polyglot java import org.enso.base.time.CustomTemporalUnits
|
polyglot java import org.enso.base.time.CustomTemporalUnits
|
||||||
|
polyglot java import org.enso.base.time.Date_Utils
|
||||||
polyglot java import org.enso.base.time.Date_Period_Utils
|
polyglot java import org.enso.base.time.Date_Period_Utils
|
||||||
|
polyglot java import org.enso.base.time.Date_Time_Utils
|
||||||
|
polyglot java import org.enso.base.time.Time_Of_Day_Utils
|
||||||
polyglot java import org.enso.base.Time_Utils
|
polyglot java import org.enso.base.Time_Utils
|
||||||
|
|
||||||
## Represents a unit of time longer on the scale of days (longer than a day).
|
## Represents a unit of time longer on the scale of days (longer than a day).
|
||||||
|
@ -25,19 +25,18 @@ from project.Data.Range.Extensions import all
|
|||||||
from project.Data.Text.Extensions import all
|
from project.Data.Text.Extensions import all
|
||||||
from project.Metadata import Display, make_single_choice, Widget
|
from project.Metadata import Display, make_single_choice, Widget
|
||||||
|
|
||||||
polyglot java import java.io.StringReader
|
|
||||||
polyglot java import java.lang.Exception as JException
|
polyglot java import java.lang.Exception as JException
|
||||||
polyglot java import javax.xml.parsers.DocumentBuilder
|
polyglot java import javax.xml.xpath.XPath
|
||||||
polyglot java import javax.xml.parsers.DocumentBuilderFactory
|
|
||||||
polyglot java import javax.xml.xpath.XPathConstants
|
polyglot java import javax.xml.xpath.XPathConstants
|
||||||
polyglot java import javax.xml.xpath.XPathFactory
|
polyglot java import javax.xml.xpath.XPathFactory
|
||||||
polyglot java import org.enso.base.XML_Utils
|
polyglot java import org.enso.base.XML_Utils
|
||||||
|
polyglot java import org.w3c.dom.Attr
|
||||||
polyglot java import org.w3c.dom.Document
|
polyglot java import org.w3c.dom.Document
|
||||||
polyglot java import org.w3c.dom.Element
|
polyglot java import org.w3c.dom.Element
|
||||||
polyglot java import org.w3c.dom.Node
|
polyglot java import org.w3c.dom.Node
|
||||||
polyglot java import org.w3c.dom.NodeList
|
polyglot java import org.w3c.dom.NodeList
|
||||||
|
polyglot java import org.w3c.dom.NamedNodeMap
|
||||||
polyglot java import org.w3c.dom.Text as Java_Text
|
polyglot java import org.w3c.dom.Text as Java_Text
|
||||||
polyglot java import org.xml.sax.InputSource
|
|
||||||
polyglot java import org.xml.sax.SAXException
|
polyglot java import org.xml.sax.SAXException
|
||||||
polyglot java import org.xml.sax.SAXParseException
|
polyglot java import org.xml.sax.SAXParseException
|
||||||
|
|
||||||
@ -75,7 +74,8 @@ type XML_Document
|
|||||||
from_stream : Input_Stream -> XML_Document ! XML_Error
|
from_stream : Input_Stream -> XML_Document ! XML_Error
|
||||||
from_stream input_stream:Input_Stream =
|
from_stream input_stream:Input_Stream =
|
||||||
XML_Error.handle_java_exceptions <|
|
XML_Error.handle_java_exceptions <|
|
||||||
input_stream.with_java_stream java_stream-> XML_Document.from_source java_stream
|
input_stream.with_java_stream java_stream->
|
||||||
|
XML_Document.Value (XML_Utils.parseStream java_stream)
|
||||||
|
|
||||||
## GROUP Conversions
|
## GROUP Conversions
|
||||||
ICON convert
|
ICON convert
|
||||||
@ -93,20 +93,13 @@ type XML_Document
|
|||||||
from_text : Text -> XML_Document ! XML_Error
|
from_text : Text -> XML_Document ! XML_Error
|
||||||
from_text xml_string:Text =
|
from_text xml_string:Text =
|
||||||
XML_Error.handle_java_exceptions <|
|
XML_Error.handle_java_exceptions <|
|
||||||
string_reader = StringReader.new xml_string
|
XML_Document.Value (XML_Utils.parseString xml_string)
|
||||||
XML_Document.from_source (InputSource.new string_reader)
|
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
Read XML from an input source.
|
Wrap Java's Document to XML_Document
|
||||||
from_source : Any -> XML_Document ! XML_Error
|
new doc:Document = XML_Document.Value doc
|
||||||
from_source input_source =
|
|
||||||
document_builder_factory = DocumentBuilderFactory.newInstance
|
|
||||||
document_builder = document_builder_factory.newDocumentBuilder
|
|
||||||
XML_Utils.setCustomErrorHandler document_builder
|
|
||||||
XML_Document.Value (document_builder.parse input_source)
|
|
||||||
|
|
||||||
## PRIVATE
|
private Value (java_document:Document)
|
||||||
Value (java_document:Document)
|
|
||||||
|
|
||||||
|
|
||||||
## GROUP Metadata
|
## GROUP Metadata
|
||||||
|
@ -24,6 +24,10 @@ from project.Metadata import make_single_choice
|
|||||||
|
|
||||||
polyglot java import org.enso.base.enso_cloud.EnsoSecretHelper
|
polyglot java import org.enso.base.enso_cloud.EnsoSecretHelper
|
||||||
polyglot java import org.enso.base.enso_cloud.HideableValue
|
polyglot java import org.enso.base.enso_cloud.HideableValue
|
||||||
|
polyglot java import org.enso.base.enso_cloud.HideableValue.PlainValue
|
||||||
|
polyglot java import org.enso.base.enso_cloud.HideableValue.SecretValue
|
||||||
|
polyglot java import org.enso.base.enso_cloud.HideableValue.ConcatValues
|
||||||
|
polyglot java import org.enso.base.enso_cloud.HideableValue.Base64EncodeValue
|
||||||
|
|
||||||
## A reference to a secret stored in the Enso Cloud.
|
## A reference to a secret stored in the Enso Cloud.
|
||||||
type Enso_Secret
|
type Enso_Secret
|
||||||
|
@ -78,7 +78,7 @@ slice vector start end = @Builtin_Method "Array_Like_Helpers.slice"
|
|||||||
`Map_Error`.
|
`Map_Error`.
|
||||||
- No_Wrap: The first error is thrown, and is not wrapped in
|
- No_Wrap: The first error is thrown, and is not wrapped in
|
||||||
`Map_Error`.
|
`Map_Error`.
|
||||||
- Report_Warning: The result for that element is `Nothing`,
|
- Report_Warning: The result for that element is `Nothing`,
|
||||||
the error is attached as a warning. Currently unimplemented.
|
the error is attached as a warning. Currently unimplemented.
|
||||||
- Ignore: The result is `Nothing`, and the error is
|
- Ignore: The result is `Nothing`, and the error is
|
||||||
ignored.
|
ignored.
|
||||||
|
@ -14,3 +14,18 @@ polyglot java import org.enso.base.text.CaseFoldedString.Grapheme
|
|||||||
|
|
||||||
# needed by Comparator_Spec:
|
# needed by Comparator_Spec:
|
||||||
polyglot java import org.enso.base.ObjectComparator
|
polyglot java import org.enso.base.ObjectComparator
|
||||||
|
|
||||||
|
# often used in tests
|
||||||
|
polyglot java import java.util.ArrayList
|
||||||
|
polyglot java import java.util.Map
|
||||||
|
polyglot java import java.nio.CharBuffer
|
||||||
|
polyglot java import java.nio.file.Path
|
||||||
|
polyglot java import java.io.FileInputStream
|
||||||
|
polyglot java import java.io.FileOutputStream
|
||||||
|
polyglot java import java.math.BigInteger
|
||||||
|
polyglot java import java.time.LocalDate
|
||||||
|
polyglot java import java.time.LocalDateTime
|
||||||
|
polyglot java import java.util.function.Function
|
||||||
|
polyglot java import java.lang.Thread
|
||||||
|
polyglot java import java.lang.Thread.State
|
||||||
|
polyglot java import java.lang.Float
|
||||||
|
@ -45,7 +45,7 @@ type Project_Description
|
|||||||
Arguments:
|
Arguments:
|
||||||
- prim_root_file: The primitive root file of the project.
|
- prim_root_file: The primitive root file of the project.
|
||||||
- prim_config: The primitive config of the project.
|
- prim_config: The primitive config of the project.
|
||||||
private Value prim_root_file prim_config
|
private Value prim_root_file ns:Text n:Text
|
||||||
|
|
||||||
## GROUP Metadata
|
## GROUP Metadata
|
||||||
ICON folder
|
ICON folder
|
||||||
@ -78,7 +78,7 @@ type Project_Description
|
|||||||
|
|
||||||
enso_project.name
|
enso_project.name
|
||||||
name : Text
|
name : Text
|
||||||
name self = self.prim_config.name
|
name self = self.n
|
||||||
|
|
||||||
## GROUP Metadata
|
## GROUP Metadata
|
||||||
ICON metadata
|
ICON metadata
|
||||||
@ -89,7 +89,7 @@ type Project_Description
|
|||||||
|
|
||||||
enso_project.namespace
|
enso_project.namespace
|
||||||
namespace : Text
|
namespace : Text
|
||||||
namespace self = self.prim_config.namespace
|
namespace self = self.ns
|
||||||
|
|
||||||
## ICON enso_icon
|
## ICON enso_icon
|
||||||
Returns the Enso project description for the project that the engine was
|
Returns the Enso project description for the project that the engine was
|
||||||
|
@ -30,12 +30,17 @@ from project.Data.Json.Extensions import all
|
|||||||
|
|
||||||
polyglot java import java.lang.Exception as JException
|
polyglot java import java.lang.Exception as JException
|
||||||
polyglot java import java.net.http.HttpClient
|
polyglot java import java.net.http.HttpClient
|
||||||
|
polyglot java import java.net.http.HttpClient.Redirect
|
||||||
|
polyglot java import java.net.http.HttpClient.Version
|
||||||
|
polyglot java import java.net.http.HttpClient.Builder as ClientBuilder
|
||||||
polyglot java import java.net.http.HttpRequest
|
polyglot java import java.net.http.HttpRequest
|
||||||
polyglot java import java.net.http.HttpRequest.BodyPublisher
|
polyglot java import java.net.http.HttpRequest.BodyPublisher
|
||||||
|
polyglot java import java.net.http.HttpRequest.BodyPublishers
|
||||||
|
polyglot java import java.net.http.HttpRequest.Builder
|
||||||
polyglot java import java.net.InetSocketAddress
|
polyglot java import java.net.InetSocketAddress
|
||||||
polyglot java import java.net.ProxySelector
|
polyglot java import java.net.ProxySelector
|
||||||
polyglot java import java.nio.file.Path
|
|
||||||
polyglot java import javax.net.ssl.SSLContext
|
polyglot java import javax.net.ssl.SSLContext
|
||||||
|
polyglot java import org.enso.base.file_system.File_Utils
|
||||||
polyglot java import org.enso.base.enso_cloud.EnsoSecretHelper
|
polyglot java import org.enso.base.enso_cloud.EnsoSecretHelper
|
||||||
polyglot java import org.enso.base.net.http.MultipartBodyBuilder
|
polyglot java import org.enso.base.net.http.MultipartBodyBuilder
|
||||||
polyglot java import org.enso.base.net.http.UrlencodedBodyBuilder
|
polyglot java import org.enso.base.net.http.UrlencodedBodyBuilder
|
||||||
@ -242,7 +247,7 @@ resolve_body_to_publisher_and_boundary body:Request_Body =
|
|||||||
json.if_not_error <|
|
json.if_not_error <|
|
||||||
Pair.new (body_publishers.ofString json) Nothing
|
Pair.new (body_publishers.ofString json) Nothing
|
||||||
Request_Body.Binary file ->
|
Request_Body.Binary file ->
|
||||||
path = Path.of file.path
|
path = File_Utils.toPath file.path
|
||||||
Pair.new (body_publishers.ofFile path) Nothing
|
Pair.new (body_publishers.ofFile path) Nothing
|
||||||
Request_Body.Form_Data form_data url_encoded ->
|
Request_Body.Form_Data form_data url_encoded ->
|
||||||
build_form_body_publisher form_data url_encoded
|
build_form_body_publisher form_data url_encoded
|
||||||
|
@ -25,6 +25,10 @@ from project.Data.Text.Extensions import all
|
|||||||
from project.Metadata import Display, Widget
|
from project.Metadata import Display, Widget
|
||||||
from project.Network.HTTP.Response_Body import decode_format_selector
|
from project.Network.HTTP.Response_Body import decode_format_selector
|
||||||
|
|
||||||
|
polyglot java import java.net.http.HttpHeaders
|
||||||
|
polyglot java import org.enso.base.enso_cloud.EnsoHttpResponse
|
||||||
|
polyglot java import java.util.Optional
|
||||||
|
|
||||||
type Response
|
type Response
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
|
|
||||||
|
@ -42,13 +42,12 @@ from project.System.File_Format import Auto_Detect, File_Format
|
|||||||
polyglot java import java.io.File as Java_File
|
polyglot java import java.io.File as Java_File
|
||||||
polyglot java import java.io.InputStream as Java_Input_Stream
|
polyglot java import java.io.InputStream as Java_Input_Stream
|
||||||
polyglot java import java.io.OutputStream as Java_Output_Stream
|
polyglot java import java.io.OutputStream as Java_Output_Stream
|
||||||
polyglot java import java.nio.file.FileSystems
|
|
||||||
polyglot java import java.nio.file.Path
|
|
||||||
polyglot java import java.nio.file.StandardCopyOption
|
polyglot java import java.nio.file.StandardCopyOption
|
||||||
polyglot java import java.nio.file.StandardOpenOption
|
polyglot java import java.nio.file.StandardOpenOption
|
||||||
polyglot java import java.time.ZonedDateTime
|
polyglot java import java.time.ZonedDateTime
|
||||||
polyglot java import org.enso.base.DryRunFileManager
|
polyglot java import org.enso.base.DryRunFileManager
|
||||||
polyglot java import org.enso.base.file_system.FileSystemSPI
|
polyglot java import org.enso.base.file_system.FileSystemSPI
|
||||||
|
polyglot java import org.enso.base.file_system.File_Utils
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
file_types : Vector
|
file_types : Vector
|
||||||
@ -795,11 +794,10 @@ type File
|
|||||||
_ ->
|
_ ->
|
||||||
used_filter = if recursive.not || name_filter.contains "**" then name_filter else
|
used_filter = if recursive.not || name_filter.contains "**" then name_filter else
|
||||||
(if name_filter.starts_with "*" then "*" else "**/") + name_filter
|
(if name_filter.starts_with "*" then "*" else "**/") + name_filter
|
||||||
fs = FileSystems.getDefault
|
matcher = File_Utils.matchPath "glob:"+used_filter
|
||||||
matcher = fs.getPathMatcher "glob:"+used_filter
|
|
||||||
all_files.filter file->
|
all_files.filter file->
|
||||||
pathStr = self.relativize file . path
|
pathStr = self.relativize file . path
|
||||||
matcher.matches (Path.of pathStr)
|
File_Utils.matches matcher pathStr
|
||||||
|
|
||||||
## GROUP Metadata
|
## GROUP Metadata
|
||||||
ICON metadata
|
ICON metadata
|
||||||
@ -894,11 +892,11 @@ Writable_File.from (that : File) = if Data_Link.is_data_link that then Data_Link
|
|||||||
## PRIVATE
|
## PRIVATE
|
||||||
local_file_copy (source : File) (destination : File) (replace_existing : Boolean) -> Nothing =
|
local_file_copy (source : File) (destination : File) (replace_existing : Boolean) -> Nothing =
|
||||||
File_Error.handle_java_exceptions source <|
|
File_Error.handle_java_exceptions source <|
|
||||||
copy_options = if replace_existing then [StandardCopyOption.REPLACE_EXISTING] else []
|
copy_options = if replace_existing then [StandardCopyOption.REPLACE_EXISTING.to_text] else []
|
||||||
source.copy_builtin destination copy_options
|
source.copy_builtin destination copy_options
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
local_file_move (source : File) (destination : File) (replace_existing : Boolean) -> Nothing =
|
local_file_move (source : File) (destination : File) (replace_existing : Boolean) -> Nothing =
|
||||||
File_Error.handle_java_exceptions source <|
|
File_Error.handle_java_exceptions source <|
|
||||||
copy_options = if replace_existing then [StandardCopyOption.REPLACE_EXISTING] else []
|
copy_options = if replace_existing then [StandardCopyOption.REPLACE_EXISTING.to_text] else []
|
||||||
source.move_builtin destination copy_options
|
source.move_builtin destination copy_options
|
||||||
|
@ -49,18 +49,20 @@ type File_Access
|
|||||||
## PRIVATE
|
## PRIVATE
|
||||||
|
|
||||||
Convert this object into a representation understandable by the JVM.
|
Convert this object into a representation understandable by the JVM.
|
||||||
to_java : StandardOpenOption
|
to_java : Text
|
||||||
to_java self = case self of
|
to_java self =
|
||||||
File_Access.Append -> StandardOpenOption.APPEND
|
java_option = case self of
|
||||||
File_Access.Create -> StandardOpenOption.CREATE
|
File_Access.Append -> StandardOpenOption.APPEND
|
||||||
File_Access.Create_New -> StandardOpenOption.CREATE_NEW
|
File_Access.Create -> StandardOpenOption.CREATE
|
||||||
File_Access.Delete_On_Close -> StandardOpenOption.DELETE_ON_CLOSE
|
File_Access.Create_New -> StandardOpenOption.CREATE_NEW
|
||||||
File_Access.Dsync -> StandardOpenOption.DSYNC
|
File_Access.Delete_On_Close -> StandardOpenOption.DELETE_ON_CLOSE
|
||||||
File_Access.Read -> StandardOpenOption.READ
|
File_Access.Dsync -> StandardOpenOption.DSYNC
|
||||||
File_Access.Sparse -> StandardOpenOption.SPARSE
|
File_Access.Read -> StandardOpenOption.READ
|
||||||
File_Access.Sync -> StandardOpenOption.SYNC
|
File_Access.Sparse -> StandardOpenOption.SPARSE
|
||||||
File_Access.Truncate_Existing -> StandardOpenOption.TRUNCATE_EXISTING
|
File_Access.Sync -> StandardOpenOption.SYNC
|
||||||
File_Access.Write -> StandardOpenOption.WRITE
|
File_Access.Truncate_Existing -> StandardOpenOption.TRUNCATE_EXISTING
|
||||||
|
File_Access.Write -> StandardOpenOption.WRITE
|
||||||
|
java_option.to_text
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
ensure_only_allowed_options (operation_name : Text) (allowed_options : Vector) (got_options : Vector) ~action =
|
ensure_only_allowed_options (operation_name : Text) (allowed_options : Vector) (got_options : Vector) ~action =
|
||||||
|
@ -3,6 +3,8 @@ import project.Data.Text.Text
|
|||||||
import project.Data.Vector.Vector
|
import project.Data.Vector.Vector
|
||||||
|
|
||||||
polyglot java import java.nio.file.attribute.PosixFilePermission
|
polyglot java import java.nio.file.attribute.PosixFilePermission
|
||||||
|
polyglot java import java.nio.file.attribute.PosixFilePermissions
|
||||||
|
polyglot java import java.util.Set
|
||||||
|
|
||||||
type Permission
|
type Permission
|
||||||
## Permission for read access for a given entity.
|
## Permission for read access for a given entity.
|
||||||
@ -101,7 +103,8 @@ type File_Permissions
|
|||||||
## PRIVATE
|
## PRIVATE
|
||||||
ADVANCED
|
ADVANCED
|
||||||
Converts a Java `Set` of Java `PosixFilePermission` to `File_Permissions`.
|
Converts a Java `Set` of Java `PosixFilePermission` to `File_Permissions`.
|
||||||
from_java_set java_set =
|
from_java_set permissions:Text =
|
||||||
|
java_set = PosixFilePermissions.fromString permissions
|
||||||
vecs = Vector.build_multiple 3 builders->
|
vecs = Vector.build_multiple 3 builders->
|
||||||
owner = builders.at 0
|
owner = builders.at 0
|
||||||
group = builders.at 1
|
group = builders.at 1
|
||||||
|
@ -23,6 +23,7 @@ polyglot java import java.io.InputStream as Java_Input_Stream
|
|||||||
polyglot java import org.enso.base.encoding.Encoding_Utils
|
polyglot java import org.enso.base.encoding.Encoding_Utils
|
||||||
polyglot java import org.enso.base.encoding.ReportingStreamDecoder
|
polyglot java import org.enso.base.encoding.ReportingStreamDecoder
|
||||||
polyglot java import org.enso.base.Stream_Utils
|
polyglot java import org.enso.base.Stream_Utils
|
||||||
|
polyglot java import org.enso.base.Stream_Utils.InputStreamLike
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
An input stream, allowing for interactive reading of contents.
|
An input stream, allowing for interactive reading of contents.
|
||||||
@ -113,7 +114,8 @@ type Input_Stream
|
|||||||
Arguments:
|
Arguments:
|
||||||
- f: Applies a function over the internal java stream.
|
- f: Applies a function over the internal java stream.
|
||||||
with_java_stream : (Java_Input_Stream -> Any) -> Any
|
with_java_stream : (Java_Input_Stream -> Any) -> Any
|
||||||
with_java_stream self f = self.stream_resource . with java_stream->
|
with_java_stream self f = self.stream_resource . with java_like_stream->
|
||||||
|
java_stream = Stream_Utils.asInputStream java_like_stream
|
||||||
self.error_handler <| f java_stream
|
self.error_handler <| f java_stream
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
@ -158,7 +160,8 @@ type Input_Stream
|
|||||||
The current stream may be invalidated after the conversion, and it should
|
The current stream may be invalidated after the conversion, and it should
|
||||||
no longer be used - only the returned stream should be used.
|
no longer be used - only the returned stream should be used.
|
||||||
as_peekable_stream self -> Input_Stream = if self.is_peekable then self else
|
as_peekable_stream self -> Input_Stream = if self.is_peekable then self else
|
||||||
raw_java_stream = self.stream_resource.take
|
raw_stream = self.stream_resource.take
|
||||||
|
raw_java_stream = Stream_Utils.asInputStream raw_stream
|
||||||
buffered_stream = BufferedInputStream.new raw_java_stream
|
buffered_stream = BufferedInputStream.new raw_java_stream
|
||||||
Input_Stream.new buffered_stream self.error_handler self.associated_source
|
Input_Stream.new buffered_stream self.error_handler self.associated_source
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ from project.Data.Boolean import Boolean, False, True
|
|||||||
from project.Runtime import assert
|
from project.Runtime import assert
|
||||||
|
|
||||||
polyglot java import org.enso.base.encoding.DecodingProblemAggregator
|
polyglot java import org.enso.base.encoding.DecodingProblemAggregator
|
||||||
|
polyglot java import org.enso.base.encoding.DecodingProblem
|
||||||
polyglot java import org.enso.base.encoding.Encoding_Utils
|
polyglot java import org.enso.base.encoding.Encoding_Utils
|
||||||
polyglot java import org.enso.base.encoding.ReportingStreamDecoder
|
polyglot java import org.enso.base.encoding.ReportingStreamDecoder
|
||||||
|
|
||||||
|
@ -15,6 +15,9 @@ from project.System.Input_Stream import close_stream
|
|||||||
polyglot java import java.io.ByteArrayOutputStream
|
polyglot java import java.io.ByteArrayOutputStream
|
||||||
polyglot java import java.io.OutputStream as Java_Output_Stream
|
polyglot java import java.io.OutputStream as Java_Output_Stream
|
||||||
polyglot java import org.enso.base.encoding.Encoding_Utils
|
polyglot java import org.enso.base.encoding.Encoding_Utils
|
||||||
|
|
||||||
|
polyglot java import org.enso.base.Stream_Utils
|
||||||
|
polyglot java import org.enso.base.Stream_Utils.OutputStreamLike
|
||||||
polyglot java import org.enso.base.encoding.ReportingStreamEncoder
|
polyglot java import org.enso.base.encoding.ReportingStreamEncoder
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
@ -57,7 +60,7 @@ type Output_Stream
|
|||||||
- stream_resource: The internal resource that represents the underlying
|
- stream_resource: The internal resource that represents the underlying
|
||||||
stream.
|
stream.
|
||||||
- error_handler: An error handler for IOExceptions thrown when writing.
|
- error_handler: An error handler for IOExceptions thrown when writing.
|
||||||
Value stream_resource error_handler
|
private Value stream_resource error_handler
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
ADVANCED
|
ADVANCED
|
||||||
@ -66,7 +69,8 @@ type Output_Stream
|
|||||||
Arguments:
|
Arguments:
|
||||||
- contents: A vector of bytes to write.
|
- contents: A vector of bytes to write.
|
||||||
write_bytes : Vector Integer -> Nothing
|
write_bytes : Vector Integer -> Nothing
|
||||||
write_bytes self contents = self.stream_resource . with java_stream->
|
write_bytes self contents = self.stream_resource . with raw_stream->
|
||||||
|
java_stream = Stream_Utils.asOutputStream raw_stream
|
||||||
self.error_handler <|
|
self.error_handler <|
|
||||||
java_stream.write contents
|
java_stream.write contents
|
||||||
java_stream.flush
|
java_stream.flush
|
||||||
@ -80,7 +84,8 @@ type Output_Stream
|
|||||||
- input_stream: An Input_Stream to write to this stream.
|
- input_stream: An Input_Stream to write to this stream.
|
||||||
write_stream : Input_Stream -> Nothing
|
write_stream : Input_Stream -> Nothing
|
||||||
write_stream self input_stream:Input_Stream =
|
write_stream self input_stream:Input_Stream =
|
||||||
self.stream_resource . with java_output_stream->
|
self.stream_resource . with raw_stream->
|
||||||
|
java_output_stream = Stream_Utils.asOutputStream raw_stream
|
||||||
self.error_handler <|
|
self.error_handler <|
|
||||||
input_stream.with_java_stream java_input_stream->
|
input_stream.with_java_stream java_input_stream->
|
||||||
java_input_stream.transferTo java_output_stream
|
java_input_stream.transferTo java_output_stream
|
||||||
@ -107,7 +112,9 @@ type Output_Stream
|
|||||||
Arguments:
|
Arguments:
|
||||||
- f: Applies a function over the internal java stream.
|
- f: Applies a function over the internal java stream.
|
||||||
with_java_stream : (Java_Output_Stream -> Any) -> Any
|
with_java_stream : (Java_Output_Stream -> Any) -> Any
|
||||||
with_java_stream self f = self.stream_resource . with f
|
with_java_stream self f = self.stream_resource . with raw_stream->
|
||||||
|
java_stream = Stream_Utils.asOutputStream raw_stream
|
||||||
|
f java_stream
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
ADVANCED
|
ADVANCED
|
||||||
|
@ -2721,13 +2721,13 @@ type Table
|
|||||||
- root_name: The name of the root tag in the XML.
|
- root_name: The name of the root tag in the XML.
|
||||||
- row_name: The name of the row tag in the XML.
|
- row_name: The name of the row tag in the XML.
|
||||||
- on_problems: Specifies how to handle warnings if they occur, reporting
|
- on_problems: Specifies how to handle warnings if they occur, reporting
|
||||||
them as warnings by default.
|
them as warnings by default.
|
||||||
|
|
||||||
! Error Conditions
|
! Error Conditions
|
||||||
|
|
||||||
- If a column in `element_columns`, `attribute_columns` or `value_column` is not in
|
- If a column in `element_columns`, `attribute_columns` or `value_column` is not in
|
||||||
the input table, a `Missing_Input_Columns` is raised as an error.
|
the input table, a `Missing_Input_Columns` is raised as an error.
|
||||||
- If any incomming columns aree not specified in one of `element_columns`,
|
- If any incomming columns aree not specified in one of `element_columns`,
|
||||||
`attribute_columns` or `value_column`, a `Unexpected_Extra_Columns`
|
`attribute_columns` or `value_column`, a `Unexpected_Extra_Columns`
|
||||||
is reported according to the `on_problems` setting.
|
is reported according to the `on_problems` setting.
|
||||||
|
|
||||||
@ -2736,10 +2736,10 @@ type Table
|
|||||||
|
|
||||||
Input Table `table`:
|
Input Table `table`:
|
||||||
|
|
||||||
Title | Author | Price | Year
|
Title | Author | Price | Year
|
||||||
------------------------+---------------------+-------+------
|
------------------------+---------------------+-------+------
|
||||||
A Tale Of Two Cities | Charles Dickens | 9.99 | 1859
|
A Tale Of Two Cities | Charles Dickens | 9.99 | 1859
|
||||||
The Great Gatsby | F. Scott Fitzgerald | 5.99 | 1925
|
The Great Gatsby | F. Scott Fitzgerald | 5.99 | 1925
|
||||||
|
|
||||||
Result `r = t.to_xml ["Year"] ["Author", "Price"] "Title" "Books" "Book"`:
|
Result `r = t.to_xml ["Year"] ["Author", "Price"] "Title" "Books" "Book"`:
|
||||||
|
|
||||||
@ -2770,9 +2770,9 @@ type Table
|
|||||||
|
|
||||||
unused_columns = columns_helper.internal_columns.filter (Filter_Condition.Is_In resolved_element_columns+resolved_attribute_columns+[resolved_value_column] Filter_Action.Remove) . map .name
|
unused_columns = columns_helper.internal_columns.filter (Filter_Condition.Is_In resolved_element_columns+resolved_attribute_columns+[resolved_value_column] Filter_Action.Remove) . map .name
|
||||||
if unused_columns.length > 0 then problem_builder.report_other_warning (Unexpected_Extra_Columns.Warning unused_columns)
|
if unused_columns.length > 0 then problem_builder.report_other_warning (Unexpected_Extra_Columns.Warning unused_columns)
|
||||||
|
|
||||||
problem_builder.attach_problems_before on_problems <|
|
problem_builder.attach_problems_before on_problems <|
|
||||||
XML_Document.Value (Java_TableToXml.to_xml self.row_count java_element_columns java_attribute_column java_value_column root_name row_name)
|
XML_Document.new (Java_TableToXml.to_xml self.row_count java_element_columns java_attribute_column java_value_column root_name row_name)
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
columns_helper : Table_Column_Helper
|
columns_helper : Table_Column_Helper
|
||||||
|
@ -205,8 +205,5 @@ type Test
|
|||||||
if i % 10 == 0 then
|
if i % 10 == 0 then
|
||||||
IO.println 'Still failing after '+i.to_text+' retries ('+loc.to_display_text+'):\n'+caught_panic.payload.to_display_text
|
IO.println 'Still failing after '+i.to_text+' retries ('+loc.to_display_text+'):\n'+caught_panic.payload.to_display_text
|
||||||
Thread.sleep milliseconds_between_attempts
|
Thread.sleep milliseconds_between_attempts
|
||||||
## TODO This used to be
|
@Tail_Call go (i+1)
|
||||||
@Tail_Call go (i+1)
|
|
||||||
We should re-add the tail call once https://github.com/enso-org/enso/issues/9251 is fixed.
|
|
||||||
go (i+1)
|
|
||||||
go 1
|
go 1
|
||||||
|
@ -207,17 +207,16 @@ state. To generate the Native Image for runner simply execute
|
|||||||
sbt> engine-runner/buildNativeImage
|
sbt> engine-runner/buildNativeImage
|
||||||
```
|
```
|
||||||
|
|
||||||
and execute the binary on a sample factorial test program
|
and execute any program with that binary - for example `test/Base_Tests`
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> runner --run engine/runner/src/test/resources/Factorial.enso 6
|
$ runner --run test/Base_Tests
|
||||||
```
|
```
|
||||||
|
|
||||||
The task that generates the Native Image, along with all the necessary
|
The task that generates the Native Image, along with all the necessary
|
||||||
configuration, reside in a separate project due to a bug in the currently used
|
configuration, makes sure that `Standard.Base` library calls into Java via
|
||||||
GraalVM version. As September 2023 it can execute all Enso code, but cannot
|
[polyglot java import](../../docs/polyglot/java.md) are compiled into the binary
|
||||||
invoke `IO.println` or other library functions that require
|
and ready to be used.
|
||||||
[polyglot java import](../../docs/polyglot/java.md), but read on...
|
|
||||||
|
|
||||||
### Engine with Espresso
|
### Engine with Espresso
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import java.util.TreeSet;
|
|||||||
import org.enso.compiler.core.ir.module.scope.imports.Polyglot;
|
import org.enso.compiler.core.ir.module.scope.imports.Polyglot;
|
||||||
import org.enso.pkg.PackageManager$;
|
import org.enso.pkg.PackageManager$;
|
||||||
import org.graalvm.nativeimage.hosted.Feature;
|
import org.graalvm.nativeimage.hosted.Feature;
|
||||||
|
import org.graalvm.nativeimage.hosted.RuntimeProxyCreation;
|
||||||
import org.graalvm.nativeimage.hosted.RuntimeReflection;
|
import org.graalvm.nativeimage.hosted.RuntimeReflection;
|
||||||
|
|
||||||
public final class EnsoLibraryFeature implements Feature {
|
public final class EnsoLibraryFeature implements Feature {
|
||||||
@ -75,6 +76,9 @@ public final class EnsoLibraryFeature implements Feature {
|
|||||||
RuntimeReflection.registerAllConstructors(clazz);
|
RuntimeReflection.registerAllConstructors(clazz);
|
||||||
RuntimeReflection.registerAllFields(clazz);
|
RuntimeReflection.registerAllFields(clazz);
|
||||||
RuntimeReflection.registerAllMethods(clazz);
|
RuntimeReflection.registerAllMethods(clazz);
|
||||||
|
if (clazz.isInterface()) {
|
||||||
|
RuntimeProxyCreation.register(clazz);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"resources":{
|
"resources":{
|
||||||
"includes":[{
|
"includes":[{
|
||||||
|
"pattern":"\\QMETA-INF/native-image/com.oracle.truffle.espresso/native-image.properties\\E"
|
||||||
|
}, {
|
||||||
"pattern":"\\QMETA-INF/org/enso/interpreter/node/expression/builtin/BuiltinMethods.metadata\\E"
|
"pattern":"\\QMETA-INF/org/enso/interpreter/node/expression/builtin/BuiltinMethods.metadata\\E"
|
||||||
}, {
|
}, {
|
||||||
"pattern":"\\QMETA-INF/org/enso/interpreter/node/expression/builtin/BuiltinTypes.metadata\\E"
|
"pattern":"\\QMETA-INF/org/enso/interpreter/node/expression/builtin/BuiltinTypes.metadata\\E"
|
||||||
@ -52,6 +54,8 @@
|
|||||||
"pattern":"\\QMETA-INF/services/java.time.zone.ZoneRulesProvider\\E"
|
"pattern":"\\QMETA-INF/services/java.time.zone.ZoneRulesProvider\\E"
|
||||||
}, {
|
}, {
|
||||||
"pattern":"\\QMETA-INF/services/javax.xml.parsers.DocumentBuilderFactory\\E"
|
"pattern":"\\QMETA-INF/services/javax.xml.parsers.DocumentBuilderFactory\\E"
|
||||||
|
}, {
|
||||||
|
"pattern":"\\QMETA-INF/services/javax.xml.parsers.SAXParserFactory\\E"
|
||||||
}, {
|
}, {
|
||||||
"pattern":"\\QMETA-INF/services/javax.xml.xpath.XPathFactory\\E"
|
"pattern":"\\QMETA-INF/services/javax.xml.xpath.XPathFactory\\E"
|
||||||
}, {
|
}, {
|
||||||
@ -166,6 +170,8 @@
|
|||||||
"pattern":"\\Qversion.json\\E"
|
"pattern":"\\Qversion.json\\E"
|
||||||
}, {
|
}, {
|
||||||
"pattern":"\\Qversion.properties\\E"
|
"pattern":"\\Qversion.properties\\E"
|
||||||
|
}, {
|
||||||
|
"pattern":"java.base:\\Qjdk/internal/icu/impl/data/icudt72b/nfkc.nrm\\E"
|
||||||
}, {
|
}, {
|
||||||
"pattern":"java.base:\\Qjdk/internal/icu/impl/data/icudt72b/uprops.icu\\E"
|
"pattern":"java.base:\\Qjdk/internal/icu/impl/data/icudt72b/uprops.icu\\E"
|
||||||
}, {
|
}, {
|
||||||
@ -597,13 +603,13 @@
|
|||||||
}]},
|
}]},
|
||||||
"bundles":[{
|
"bundles":[{
|
||||||
"name":"com.oracle.js.parser.resources.Messages",
|
"name":"com.oracle.js.parser.resources.Messages",
|
||||||
"locales":[""]
|
"locales":["", "und"]
|
||||||
}, {
|
}, {
|
||||||
"name":"com.sun.org.apache.xerces.internal.impl.msg.XMLMessages",
|
"name":"com.sun.org.apache.xerces.internal.impl.msg.XMLMessages",
|
||||||
"locales":[""]
|
"locales":["", "und"]
|
||||||
}, {
|
}, {
|
||||||
"name":"com.sun.org.apache.xml.internal.serializer.XMLEntities",
|
"name":"com.sun.org.apache.xml.internal.serializer.XMLEntities",
|
||||||
"locales":[""]
|
"locales":["", "und"]
|
||||||
}, {
|
}, {
|
||||||
"name":"com.sun.org.apache.xml.internal.serializer.utils.SerializerMessages",
|
"name":"com.sun.org.apache.xml.internal.serializer.utils.SerializerMessages",
|
||||||
"classNames":["com.sun.org.apache.xml.internal.serializer.utils.SerializerMessages", "com.sun.org.apache.xml.internal.serializer.utils.SerializerMessages_en"]
|
"classNames":["com.sun.org.apache.xml.internal.serializer.utils.SerializerMessages", "com.sun.org.apache.xml.internal.serializer.utils.SerializerMessages_en"]
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
import Standard.Base.Data.Numbers
|
|
||||||
import Standard.Base.IO
|
|
||||||
|
|
||||||
fac n =
|
|
||||||
facacc n v = if n <= 1 then v else @Tail_Call facacc n-1 n*v
|
|
||||||
|
|
||||||
res = facacc n 1
|
|
||||||
res
|
|
||||||
|
|
||||||
main number=5 =
|
|
||||||
v = fac number
|
|
||||||
IO.println v
|
|
@ -183,13 +183,17 @@ public abstract class HostMethodCallNode extends Node {
|
|||||||
return PolyglotCallType.CONVERT_TO_HASH_MAP;
|
return PolyglotCallType.CONVERT_TO_HASH_MAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
String methodName = symbol.getName();
|
try {
|
||||||
if (library.isMemberInvocable(self, methodName)) {
|
String methodName = symbol.getName();
|
||||||
return PolyglotCallType.CALL_METHOD;
|
if (library.isMemberInvocable(self, methodName)) {
|
||||||
} else if (library.isMemberReadable(self, methodName)) {
|
return PolyglotCallType.CALL_METHOD;
|
||||||
return PolyglotCallType.GET_MEMBER;
|
} else if (library.isMemberReadable(self, methodName)) {
|
||||||
} else if (library.isInstantiable(self) && methodName.equals(NEW_NAME)) {
|
return PolyglotCallType.GET_MEMBER;
|
||||||
return PolyglotCallType.INSTANTIATE;
|
} else if (library.isInstantiable(self) && methodName.equals(NEW_NAME)) {
|
||||||
|
return PolyglotCallType.INSTANTIATE;
|
||||||
|
}
|
||||||
|
} catch (TypeNotPresentException ex) {
|
||||||
|
// no call, get or instantiate is possible
|
||||||
}
|
}
|
||||||
return PolyglotCallType.NOT_SUPPORTED;
|
return PolyglotCallType.NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
@ -98,10 +98,11 @@ public abstract class EnsoProjectNode extends Node {
|
|||||||
|
|
||||||
private static Atom createProjectDescriptionAtom(EnsoContext ctx, Package<TruffleFile> pkg) {
|
private static Atom createProjectDescriptionAtom(EnsoContext ctx, Package<TruffleFile> pkg) {
|
||||||
var rootPath = new EnsoFile(pkg.root().normalize());
|
var rootPath = new EnsoFile(pkg.root().normalize());
|
||||||
var cfg = ctx.asGuestValue(pkg.getConfig());
|
var namespace = pkg.getConfig().namespace();
|
||||||
|
var name = pkg.getConfig().name();
|
||||||
var cons = ctx.getBuiltins().getProjectDescription().getUniqueConstructor();
|
var cons = ctx.getBuiltins().getProjectDescription().getUniqueConstructor();
|
||||||
|
|
||||||
return AtomNewInstanceNode.getUncached().newInstance(cons, rootPath, cfg);
|
return AtomNewInstanceNode.getUncached().newInstance(cons, rootPath, namespace, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataflowError unsupportedArgsError(Object moduleActual) {
|
private DataflowError unsupportedArgsError(Object moduleActual) {
|
||||||
|
@ -13,6 +13,6 @@ public class ProjectDescription extends UniquelyConstructibleBuiltin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<String> getConstructorParamNames() {
|
protected List<String> getConstructorParamNames() {
|
||||||
return List.of("prim_root_file", "prim_config");
|
return List.of("prim_root_file", "ns", "n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,13 @@ import com.oracle.truffle.api.CompilerDirectives;
|
|||||||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
||||||
import com.oracle.truffle.api.TruffleFile;
|
import com.oracle.truffle.api.TruffleFile;
|
||||||
import com.oracle.truffle.api.dsl.Bind;
|
import com.oracle.truffle.api.dsl.Bind;
|
||||||
|
import com.oracle.truffle.api.dsl.Cached;
|
||||||
|
import com.oracle.truffle.api.interop.ArityException;
|
||||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||||
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
|
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
|
||||||
|
import com.oracle.truffle.api.interop.UnknownIdentifierException;
|
||||||
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
||||||
|
import com.oracle.truffle.api.interop.UnsupportedTypeException;
|
||||||
import com.oracle.truffle.api.library.CachedLibrary;
|
import com.oracle.truffle.api.library.CachedLibrary;
|
||||||
import com.oracle.truffle.api.library.ExportLibrary;
|
import com.oracle.truffle.api.library.ExportLibrary;
|
||||||
import com.oracle.truffle.api.library.ExportMessage;
|
import com.oracle.truffle.api.library.ExportMessage;
|
||||||
@ -22,16 +26,22 @@ import java.nio.file.LinkOption;
|
|||||||
import java.nio.file.NoSuchFileException;
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.nio.file.NotDirectoryException;
|
import java.nio.file.NotDirectoryException;
|
||||||
import java.nio.file.OpenOption;
|
import java.nio.file.OpenOption;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.nio.file.StandardOpenOption;
|
import java.nio.file.StandardOpenOption;
|
||||||
import java.nio.file.attribute.PosixFilePermission;
|
import java.nio.file.attribute.PosixFilePermissions;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.IntFunction;
|
import java.util.function.Function;
|
||||||
import org.enso.interpreter.dsl.Builtin;
|
import org.enso.interpreter.dsl.Builtin;
|
||||||
import org.enso.interpreter.runtime.EnsoContext;
|
import org.enso.interpreter.runtime.EnsoContext;
|
||||||
import org.enso.interpreter.runtime.data.text.Text;
|
import org.enso.interpreter.runtime.data.text.Text;
|
||||||
|
import org.enso.interpreter.runtime.data.vector.ArrayLikeAtNode;
|
||||||
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
|
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
|
||||||
|
import org.enso.interpreter.runtime.data.vector.ArrayLikeLengthNode;
|
||||||
import org.enso.interpreter.runtime.error.PanicException;
|
import org.enso.interpreter.runtime.error.PanicException;
|
||||||
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
|
||||||
|
|
||||||
@ -54,60 +64,273 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
|
|
||||||
@Builtin.Method(name = "output_stream_builtin")
|
@Builtin.Method(name = "output_stream_builtin")
|
||||||
@Builtin.WrapException(from = IOException.class)
|
@Builtin.WrapException(from = IOException.class)
|
||||||
@Builtin.ReturningGuestObject
|
|
||||||
@Builtin.Specialize
|
@Builtin.Specialize
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public OutputStream outputStream(Object opts, EnsoContext ctx) throws IOException {
|
public EnsoObject outputStream(
|
||||||
OpenOption[] openOptions =
|
Object opts,
|
||||||
convertInteropArray(opts, InteropLibrary.getUncached(), ctx, OpenOption[]::new);
|
@Cached ArrayLikeLengthNode lengthNode,
|
||||||
return this.truffleFile.newOutputStream(openOptions);
|
@Cached ArrayLikeAtNode atNode,
|
||||||
|
EnsoContext ctx)
|
||||||
|
throws IOException {
|
||||||
|
var options = namesToValues(opts, lengthNode, atNode, ctx, StandardOpenOption::valueOf);
|
||||||
|
var os = this.truffleFile.newOutputStream(options.toArray(OpenOption[]::new));
|
||||||
|
return new EnsoOutputStream(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportLibrary(InteropLibrary.class)
|
||||||
|
static final class EnsoOutputStream implements EnsoObject {
|
||||||
|
private static final String[] MEMBERS = new String[] {"write", "flush", "close"};
|
||||||
|
private final OutputStream os;
|
||||||
|
|
||||||
|
EnsoOutputStream(OutputStream os) {
|
||||||
|
this.os = os;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
boolean hasMembers() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@TruffleBoundary
|
||||||
|
@ExportMessage
|
||||||
|
boolean isMemberInvocable(String member) {
|
||||||
|
return Arrays.asList(MEMBERS).contains(member);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
Object getMembers(boolean includeInternal) throws UnsupportedMessageException {
|
||||||
|
return ArrayLikeHelpers.wrapStrings(MEMBERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TruffleBoundary
|
||||||
|
@ExportMessage
|
||||||
|
Object invokeMember(
|
||||||
|
String name,
|
||||||
|
Object[] args,
|
||||||
|
@Cached ArrayLikeLengthNode lengthNode,
|
||||||
|
@Cached ArrayLikeAtNode atNode,
|
||||||
|
@CachedLibrary(limit = "3") InteropLibrary iop)
|
||||||
|
throws ArityException, UnsupportedMessageException, UnknownIdentifierException {
|
||||||
|
try {
|
||||||
|
return switch (name) {
|
||||||
|
case "write" -> {
|
||||||
|
long from;
|
||||||
|
long to;
|
||||||
|
switch (args.length) {
|
||||||
|
case 1 -> {
|
||||||
|
from = 0;
|
||||||
|
to = lengthNode.executeLength(args[0]);
|
||||||
|
}
|
||||||
|
case 3 -> {
|
||||||
|
from = iop.asLong(args[1]);
|
||||||
|
to = from + iop.asLong(args[2]);
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
throw ArityException.create(1, 3, args.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (long i = from; i < to; i++) {
|
||||||
|
var elem = atNode.executeAt(args[0], i);
|
||||||
|
var byt = iop.asInt(elem);
|
||||||
|
os.write(byt);
|
||||||
|
}
|
||||||
|
yield this;
|
||||||
|
}
|
||||||
|
case "flush" -> {
|
||||||
|
os.flush();
|
||||||
|
yield this;
|
||||||
|
}
|
||||||
|
case "close" -> {
|
||||||
|
os.close();
|
||||||
|
yield this;
|
||||||
|
}
|
||||||
|
default -> throw UnknownIdentifierException.create(name);
|
||||||
|
};
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw raiseIOException(iop, ex);
|
||||||
|
} catch (InvalidArrayIndexException ex) {
|
||||||
|
var ctx = EnsoContext.get(iop);
|
||||||
|
throw ctx.raiseAssertionPanic(iop, name, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "EnsoOutputStream";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method(name = "input_stream_builtin")
|
@Builtin.Method(name = "input_stream_builtin")
|
||||||
@Builtin.WrapException(from = IOException.class)
|
@Builtin.WrapException(from = IOException.class)
|
||||||
@Builtin.Specialize
|
@Builtin.Specialize
|
||||||
@Builtin.ReturningGuestObject
|
@TruffleBoundary
|
||||||
@CompilerDirectives.TruffleBoundary
|
public EnsoObject inputStream(
|
||||||
public InputStream inputStream(Object opts, EnsoContext ctx) throws IOException {
|
Object opts,
|
||||||
OpenOption[] openOptions =
|
@Cached ArrayLikeLengthNode lengthNode,
|
||||||
convertInteropArray(opts, InteropLibrary.getUncached(), ctx, OpenOption[]::new);
|
@Cached ArrayLikeAtNode atNode,
|
||||||
return this.truffleFile.newInputStream(openOptions);
|
EnsoContext ctx)
|
||||||
|
throws IOException {
|
||||||
|
var options = namesToValues(opts, lengthNode, atNode, ctx, StandardOpenOption::valueOf);
|
||||||
|
var is = this.truffleFile.newInputStream(options.toArray(OpenOption[]::new));
|
||||||
|
return new EnsoInputStream(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportLibrary(InteropLibrary.class)
|
||||||
|
static final class EnsoInputStream implements EnsoObject {
|
||||||
|
private static final String[] MEMBERS =
|
||||||
|
new String[] {
|
||||||
|
"read", "readAllBytes", "readNBytes", "skipNBytes", "markSupported", "available", "close"
|
||||||
|
};
|
||||||
|
private final InputStream is;
|
||||||
|
|
||||||
|
EnsoInputStream(InputStream is) {
|
||||||
|
this.is = is;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
boolean hasMembers() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@TruffleBoundary
|
||||||
|
@ExportMessage
|
||||||
|
boolean isMemberInvocable(String member) {
|
||||||
|
return Arrays.asList(MEMBERS).contains(member);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
|
Object getMembers(boolean includeInternal) throws UnsupportedMessageException {
|
||||||
|
return ArrayLikeHelpers.wrapStrings(MEMBERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TruffleBoundary
|
||||||
|
@ExportMessage
|
||||||
|
Object invokeMember(String name, Object[] args, @CachedLibrary(limit = "3") InteropLibrary iop)
|
||||||
|
throws UnknownIdentifierException,
|
||||||
|
UnsupportedMessageException,
|
||||||
|
ArityException,
|
||||||
|
UnsupportedTypeException {
|
||||||
|
try {
|
||||||
|
return switch (name) {
|
||||||
|
case "read" -> {
|
||||||
|
if (args.length == 0) {
|
||||||
|
yield is.read();
|
||||||
|
}
|
||||||
|
long from;
|
||||||
|
long to;
|
||||||
|
switch (args.length) {
|
||||||
|
case 1 -> {
|
||||||
|
from = 0;
|
||||||
|
to = iop.getArraySize(args[0]);
|
||||||
|
}
|
||||||
|
case 3 -> {
|
||||||
|
from = iop.asLong(args[1]);
|
||||||
|
to = from + iop.asLong(args[2]);
|
||||||
|
}
|
||||||
|
default -> throw ArityException.create(0, 3, args.length);
|
||||||
|
}
|
||||||
|
for (var i = from; i < to; i++) {
|
||||||
|
var b = is.read();
|
||||||
|
if (b == -1) {
|
||||||
|
var count = i - from;
|
||||||
|
yield count > 0 ? count : -1;
|
||||||
|
}
|
||||||
|
iop.writeArrayElement(args[0], i, (byte) b);
|
||||||
|
}
|
||||||
|
yield to - from;
|
||||||
|
}
|
||||||
|
case "readAllBytes" -> {
|
||||||
|
if (args.length != 0) {
|
||||||
|
throw ArityException.create(0, 0, args.length);
|
||||||
|
}
|
||||||
|
var arr = is.readAllBytes();
|
||||||
|
var buf = ByteBuffer.wrap(arr);
|
||||||
|
yield ArrayLikeHelpers.wrapBuffer(buf);
|
||||||
|
}
|
||||||
|
case "readNBytes" -> {
|
||||||
|
if (args.length != 1) {
|
||||||
|
throw ArityException.create(1, 1, args.length);
|
||||||
|
}
|
||||||
|
var len = iop.asInt(args[0]);
|
||||||
|
var arr = is.readNBytes(len);
|
||||||
|
var buf = ByteBuffer.wrap(arr);
|
||||||
|
yield ArrayLikeHelpers.wrapBuffer(buf);
|
||||||
|
}
|
||||||
|
case "skipNBytes" -> {
|
||||||
|
if (args.length != 1) {
|
||||||
|
throw ArityException.create(1, 1, args.length);
|
||||||
|
}
|
||||||
|
var len = iop.asInt(args[0]);
|
||||||
|
is.skipNBytes(len);
|
||||||
|
yield this;
|
||||||
|
}
|
||||||
|
case "markSupported" -> {
|
||||||
|
if (args.length != 0) {
|
||||||
|
throw ArityException.create(0, 0, args.length);
|
||||||
|
}
|
||||||
|
yield is.markSupported();
|
||||||
|
}
|
||||||
|
case "available" -> {
|
||||||
|
if (args.length != 0) {
|
||||||
|
throw ArityException.create(0, 0, args.length);
|
||||||
|
}
|
||||||
|
yield is.available();
|
||||||
|
}
|
||||||
|
case "close" -> {
|
||||||
|
if (args.length != 0) {
|
||||||
|
throw ArityException.create(0, 0, args.length);
|
||||||
|
}
|
||||||
|
is.close();
|
||||||
|
yield this;
|
||||||
|
}
|
||||||
|
default -> throw UnknownIdentifierException.create(name);
|
||||||
|
};
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw raiseIOException(iop, ex);
|
||||||
|
} catch (InvalidArrayIndexException ex) {
|
||||||
|
var ctx = EnsoContext.get(iop);
|
||||||
|
throw ctx.raiseAssertionPanic(iop, name, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "EnsoInputStream";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private static <T> T[] convertInteropArray(
|
@TruffleBoundary
|
||||||
Object arr, InteropLibrary interop, EnsoContext ctx, IntFunction<T[]> hostArrayCtor) {
|
private static <T> List<T> namesToValues(
|
||||||
if (!interop.hasArrayElements(arr)) {
|
Object arr,
|
||||||
var vecType = ctx.getBuiltins().vector().getType();
|
ArrayLikeLengthNode lengthNode,
|
||||||
var typeError = ctx.getBuiltins().error().makeTypeError(vecType, arr, "opts");
|
ArrayLikeAtNode atNode,
|
||||||
throw new PanicException(typeError, interop);
|
EnsoContext ctx,
|
||||||
}
|
Function<String, T> convertor) {
|
||||||
T[] hostArr;
|
var size = (int) lengthNode.executeLength(arr);
|
||||||
|
List<T> hostArr = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
int size = Math.toIntExact(interop.getArraySize(arr));
|
for (var i = 0; i < size; i++) {
|
||||||
hostArr = hostArrayCtor.apply(size);
|
var elem = atNode.executeAt(arr, i);
|
||||||
for (int i = 0; i < size; i++) {
|
if (elem instanceof Text name) {
|
||||||
Object elem = interop.readArrayElement(arr, i);
|
hostArr.add(convertor.apply(name.toString()));
|
||||||
if (!ctx.isJavaPolyglotObject(elem)) {
|
} else {
|
||||||
var err =
|
var err =
|
||||||
ctx.getBuiltins()
|
ctx.getBuiltins()
|
||||||
.error()
|
.error()
|
||||||
.makeUnsupportedArgumentsError(
|
.makeTypeError(ctx.getBuiltins().text(), elem, "File_Access permissions");
|
||||||
new Object[] {arr},
|
throw new PanicException(err, lengthNode);
|
||||||
"Arguments to opts should be host objects from java.io package");
|
|
||||||
throw new PanicException(err, interop);
|
|
||||||
}
|
}
|
||||||
hostArr[i] = (T) ctx.asJavaPolyglotObject(elem);
|
|
||||||
}
|
}
|
||||||
} catch (ClassCastException | UnsupportedMessageException | InvalidArrayIndexException e) {
|
} catch (ClassCastException | InvalidArrayIndexException e) {
|
||||||
throw EnsoContext.get(interop).raiseAssertionPanic(interop, null, e);
|
throw EnsoContext.get(lengthNode).raiseAssertionPanic(lengthNode, null, e);
|
||||||
}
|
}
|
||||||
return hostArr;
|
return hostArr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method(name = "read_last_bytes_builtin")
|
@Builtin.Method(name = "read_last_bytes_builtin")
|
||||||
@Builtin.WrapException(from = IOException.class)
|
@Builtin.WrapException(from = IOException.class)
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public EnsoObject readLastBytes(long n) throws IOException {
|
public EnsoObject readLastBytes(long n) throws IOException {
|
||||||
try (SeekableByteChannel channel =
|
try (SeekableByteChannel channel =
|
||||||
this.truffleFile.newByteChannel(Set.of(StandardOpenOption.READ))) {
|
this.truffleFile.newByteChannel(Set.of(StandardOpenOption.READ))) {
|
||||||
@ -136,7 +359,7 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
|
|
||||||
@Builtin.Method(name = "creation_time_builtin")
|
@Builtin.Method(name = "creation_time_builtin")
|
||||||
@Builtin.WrapException(from = IOException.class)
|
@Builtin.WrapException(from = IOException.class)
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public EnsoDateTime getCreationTime() throws IOException {
|
public EnsoDateTime getCreationTime() throws IOException {
|
||||||
return new EnsoDateTime(
|
return new EnsoDateTime(
|
||||||
ZonedDateTime.ofInstant(truffleFile.getCreationTime().toInstant(), ZoneOffset.UTC));
|
ZonedDateTime.ofInstant(truffleFile.getCreationTime().toInstant(), ZoneOffset.UTC));
|
||||||
@ -144,7 +367,7 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
|
|
||||||
@Builtin.Method(name = "last_modified_time_builtin")
|
@Builtin.Method(name = "last_modified_time_builtin")
|
||||||
@Builtin.WrapException(from = IOException.class)
|
@Builtin.WrapException(from = IOException.class)
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public EnsoDateTime getLastModifiedTime() throws IOException {
|
public EnsoDateTime getLastModifiedTime() throws IOException {
|
||||||
return new EnsoDateTime(
|
return new EnsoDateTime(
|
||||||
ZonedDateTime.ofInstant(truffleFile.getLastModifiedTime().toInstant(), ZoneOffset.UTC));
|
ZonedDateTime.ofInstant(truffleFile.getLastModifiedTime().toInstant(), ZoneOffset.UTC));
|
||||||
@ -152,14 +375,13 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
|
|
||||||
@Builtin.Method(name = "posix_permissions_builtin")
|
@Builtin.Method(name = "posix_permissions_builtin")
|
||||||
@Builtin.WrapException(from = IOException.class)
|
@Builtin.WrapException(from = IOException.class)
|
||||||
@Builtin.ReturningGuestObject
|
@TruffleBoundary
|
||||||
@CompilerDirectives.TruffleBoundary
|
public Text getPosixPermissions() throws IOException {
|
||||||
public Set<PosixFilePermission> getPosixPermissions() throws IOException {
|
return Text.create(PosixFilePermissions.toString(truffleFile.getPosixPermissions()));
|
||||||
return truffleFile.getPosixPermissions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method(name = "parent")
|
@Builtin.Method(name = "parent")
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public EnsoObject getParent() {
|
public EnsoObject getParent() {
|
||||||
// Normalization is needed to correctly handle paths containing `..` and `.`.
|
// Normalization is needed to correctly handle paths containing `..` and `.`.
|
||||||
var parentOrNull = this.normalize().truffleFile.getParent();
|
var parentOrNull = this.normalize().truffleFile.getParent();
|
||||||
@ -179,32 +401,32 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method(name = "absolute")
|
@Builtin.Method(name = "absolute")
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public EnsoFile getAbsoluteFile() {
|
public EnsoFile getAbsoluteFile() {
|
||||||
return new EnsoFile(this.truffleFile.getAbsoluteFile());
|
return new EnsoFile(this.truffleFile.getAbsoluteFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method(name = "path")
|
@Builtin.Method(name = "path")
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public Text getPath() {
|
public Text getPath() {
|
||||||
return Text.create(this.truffleFile.getPath());
|
return Text.create(this.truffleFile.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method
|
@Builtin.Method
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public boolean isAbsolute() {
|
public boolean isAbsolute() {
|
||||||
return this.truffleFile.isAbsolute();
|
return this.truffleFile.isAbsolute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method
|
@Builtin.Method
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public boolean isDirectory() {
|
public boolean isDirectory() {
|
||||||
return this.truffleFile.isDirectory();
|
return this.truffleFile.isDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method(name = "create_directory_builtin")
|
@Builtin.Method(name = "create_directory_builtin")
|
||||||
@Builtin.WrapException(from = IOException.class)
|
@Builtin.WrapException(from = IOException.class)
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public void createDirectories() throws IOException {
|
public void createDirectories() throws IOException {
|
||||||
try {
|
try {
|
||||||
this.truffleFile.createDirectories();
|
this.truffleFile.createDirectories();
|
||||||
@ -282,32 +504,32 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
|
|
||||||
@Builtin.Method(name = "list_immediate_children_array")
|
@Builtin.Method(name = "list_immediate_children_array")
|
||||||
@Builtin.WrapException(from = IOException.class)
|
@Builtin.WrapException(from = IOException.class)
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public EnsoObject list() throws IOException {
|
public EnsoObject list() throws IOException {
|
||||||
return ArrayLikeHelpers.wrapEnsoObjects(
|
return ArrayLikeHelpers.wrapEnsoObjects(
|
||||||
this.truffleFile.list().stream().map(EnsoFile::new).toArray(EnsoFile[]::new));
|
this.truffleFile.list().stream().map(EnsoFile::new).toArray(EnsoFile[]::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method
|
@Builtin.Method
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public EnsoFile relativize(EnsoFile other) {
|
public EnsoFile relativize(EnsoFile other) {
|
||||||
return new EnsoFile(this.truffleFile.relativize(other.truffleFile));
|
return new EnsoFile(this.truffleFile.relativize(other.truffleFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method
|
@Builtin.Method
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public boolean isRegularFile() {
|
public boolean isRegularFile() {
|
||||||
return this.truffleFile.isRegularFile();
|
return this.truffleFile.isRegularFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method
|
@Builtin.Method
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public boolean isWritable() {
|
public boolean isWritable() {
|
||||||
return this.truffleFile.isWritable();
|
return this.truffleFile.isWritable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method(name = "name")
|
@Builtin.Method(name = "name")
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public Text getName() {
|
public Text getName() {
|
||||||
var name = this.normalize().truffleFile.getName();
|
var name = this.normalize().truffleFile.getName();
|
||||||
return Text.create(name == null ? "/" : name);
|
return Text.create(name == null ? "/" : name);
|
||||||
@ -315,7 +537,7 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
|
|
||||||
@Builtin.Method(name = "size_builtin")
|
@Builtin.Method(name = "size_builtin")
|
||||||
@Builtin.WrapException(from = IOException.class)
|
@Builtin.WrapException(from = IOException.class)
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public long getSize() throws IOException {
|
public long getSize() throws IOException {
|
||||||
if (this.truffleFile.isDirectory()) {
|
if (this.truffleFile.isDirectory()) {
|
||||||
throw new IOException("size can only be called on files.");
|
throw new IOException("size can only be called on files.");
|
||||||
@ -334,7 +556,7 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method
|
@Builtin.Method
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public EnsoFile normalize() {
|
public EnsoFile normalize() {
|
||||||
TruffleFile simplyNormalized = truffleFile.normalize();
|
TruffleFile simplyNormalized = truffleFile.normalize();
|
||||||
String name = simplyNormalized.getName();
|
String name = simplyNormalized.getName();
|
||||||
@ -347,7 +569,7 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
|
|
||||||
@Builtin.Method(name = "delete_builtin")
|
@Builtin.Method(name = "delete_builtin")
|
||||||
@Builtin.WrapException(from = IOException.class)
|
@Builtin.WrapException(from = IOException.class)
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public void delete(boolean recursive) throws IOException {
|
public void delete(boolean recursive) throws IOException {
|
||||||
if (recursive && truffleFile.isDirectory(LinkOption.NOFOLLOW_LINKS)) {
|
if (recursive && truffleFile.isDirectory(LinkOption.NOFOLLOW_LINKS)) {
|
||||||
deleteRecursively(truffleFile);
|
deleteRecursively(truffleFile);
|
||||||
@ -368,25 +590,35 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
@Builtin.Method(name = "copy_builtin", description = "Copy this file to a target destination")
|
@Builtin.Method(name = "copy_builtin", description = "Copy this file to a target destination")
|
||||||
@Builtin.WrapException(from = IOException.class)
|
@Builtin.WrapException(from = IOException.class)
|
||||||
@Builtin.Specialize
|
@Builtin.Specialize
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public void copy(EnsoFile target, Object options, EnsoContext ctx) throws IOException {
|
public void copy(
|
||||||
CopyOption[] copyOptions =
|
EnsoFile target,
|
||||||
convertInteropArray(options, InteropLibrary.getUncached(), ctx, CopyOption[]::new);
|
Object options,
|
||||||
truffleFile.copy(target.truffleFile, copyOptions);
|
@Cached ArrayLikeLengthNode lengthNode,
|
||||||
|
@Cached ArrayLikeAtNode atNode,
|
||||||
|
EnsoContext ctx)
|
||||||
|
throws IOException {
|
||||||
|
var copyOptions = namesToValues(options, lengthNode, atNode, ctx, StandardCopyOption::valueOf);
|
||||||
|
truffleFile.copy(target.truffleFile, copyOptions.toArray(CopyOption[]::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method(name = "move_builtin", description = "Move this file to a target destination")
|
@Builtin.Method(name = "move_builtin", description = "Move this file to a target destination")
|
||||||
@Builtin.WrapException(from = IOException.class)
|
@Builtin.WrapException(from = IOException.class)
|
||||||
@Builtin.Specialize
|
@Builtin.Specialize
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public void move(EnsoFile target, Object options, EnsoContext ctx) throws IOException {
|
public void move(
|
||||||
CopyOption[] copyOptions =
|
EnsoFile target,
|
||||||
convertInteropArray(options, InteropLibrary.getUncached(), ctx, CopyOption[]::new);
|
Object options,
|
||||||
truffleFile.move(target.truffleFile, copyOptions);
|
@Cached ArrayLikeLengthNode lengthNode,
|
||||||
|
@Cached ArrayLikeAtNode atNode,
|
||||||
|
EnsoContext ctx)
|
||||||
|
throws IOException {
|
||||||
|
var copyOptions = namesToValues(options, lengthNode, atNode, ctx, StandardCopyOption::valueOf);
|
||||||
|
truffleFile.move(target.truffleFile, copyOptions.toArray(CopyOption[]::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builtin.Method
|
@Builtin.Method
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public boolean startsWith(EnsoFile parent) {
|
public boolean startsWith(EnsoFile parent) {
|
||||||
return truffleFile.startsWith(parent.truffleFile);
|
return truffleFile.startsWith(parent.truffleFile);
|
||||||
}
|
}
|
||||||
@ -397,7 +629,7 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
"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)
|
autoRegister = false)
|
||||||
@Builtin.Specialize
|
@Builtin.Specialize
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public static EnsoFile fromString(EnsoContext context, String path) {
|
public static EnsoFile fromString(EnsoContext context, String path) {
|
||||||
TruffleFile file = context.getPublicTruffleFile(path);
|
TruffleFile file = context.getPublicTruffleFile(path);
|
||||||
return new EnsoFile(file);
|
return new EnsoFile(file);
|
||||||
@ -408,7 +640,7 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
description = "A file corresponding to the current working directory.",
|
description = "A file corresponding to the current working directory.",
|
||||||
autoRegister = false)
|
autoRegister = false)
|
||||||
@Builtin.Specialize
|
@Builtin.Specialize
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public static EnsoFile currentDirectory(EnsoContext context) {
|
public static EnsoFile currentDirectory(EnsoContext context) {
|
||||||
TruffleFile file = context.getCurrentWorkingDirectory();
|
TruffleFile file = context.getCurrentWorkingDirectory();
|
||||||
return new EnsoFile(file);
|
return new EnsoFile(file);
|
||||||
@ -419,13 +651,13 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
description = "Gets the user's system-defined home directory.",
|
description = "Gets the user's system-defined home directory.",
|
||||||
autoRegister = false)
|
autoRegister = false)
|
||||||
@Builtin.Specialize
|
@Builtin.Specialize
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public static EnsoFile userHome(EnsoContext context) {
|
public static EnsoFile userHome(EnsoContext context) {
|
||||||
return fromString(context, System.getProperty("user.home"));
|
return fromString(context, System.getProperty("user.home"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CompilerDirectives.TruffleBoundary
|
@TruffleBoundary
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "(File " + truffleFile.getPath() + ")";
|
return "(File " + truffleFile.getPath() + ")";
|
||||||
}
|
}
|
||||||
@ -449,4 +681,10 @@ public final class EnsoFile implements EnsoObject {
|
|||||||
Type getType(@Bind("$node") Node node) {
|
Type getType(@Bind("$node") Node node) {
|
||||||
return EnsoContext.get(node).getBuiltins().file();
|
return EnsoContext.get(node).getBuiltins().file();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static RuntimeException raiseIOException(Node where, IOException ex) {
|
||||||
|
var ctx = EnsoContext.get(where);
|
||||||
|
var guestEx = ctx.asGuestValue(ex);
|
||||||
|
throw new PanicException(guestEx, where);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,8 +111,12 @@ public final class PanicException extends AbstractTruffleException implements En
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NeverDefault
|
@NeverDefault
|
||||||
static UnresolvedSymbol toDisplayText(IndirectInvokeMethodNode payloads) {
|
static UnresolvedSymbol toDisplayText(IndirectInvokeMethodNode payloads)
|
||||||
|
throws UnsupportedMessageException {
|
||||||
var ctx = EnsoContext.get(payloads);
|
var ctx = EnsoContext.get(payloads);
|
||||||
|
if (ctx == null) {
|
||||||
|
throw UnsupportedMessageException.create();
|
||||||
|
}
|
||||||
var scope = ctx.getBuiltins().panic().getDefinitionScope();
|
var scope = ctx.getBuiltins().panic().getDefinitionScope();
|
||||||
return UnresolvedSymbol.build("to_display_text", scope);
|
return UnresolvedSymbol.build("to_display_text", scope);
|
||||||
}
|
}
|
||||||
|
@ -24,26 +24,31 @@ public final class Parser implements AutoCloseable {
|
|||||||
name = "libenso_parser.so";
|
name = "libenso_parser.so";
|
||||||
}
|
}
|
||||||
|
|
||||||
File parser = null;
|
var whereAmI = Parser.class.getProtectionDomain().getCodeSource().getLocation();
|
||||||
|
File root;
|
||||||
try {
|
try {
|
||||||
var whereAmI = Parser.class.getProtectionDomain().getCodeSource().getLocation();
|
root = new File(whereAmI.toURI()).getParentFile();
|
||||||
var d = new File(whereAmI.toURI()).getParentFile();
|
} catch (URISyntaxException ex) {
|
||||||
|
root = new File(".").getAbsoluteFile();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var d = root;
|
||||||
File path = null;
|
File path = null;
|
||||||
while (d != null) {
|
while (d != null) {
|
||||||
path = new File(d, name);
|
path = new File(d, name);
|
||||||
if (path.exists()) break;
|
if (path.exists()) break;
|
||||||
d = d.getParentFile();
|
d = d.getParentFile();
|
||||||
}
|
}
|
||||||
if (d == null) {
|
if (d == null || path == null) {
|
||||||
throw new LinkageError(
|
throw new LinkageError("Cannot find parser in " + root);
|
||||||
"Cannot find parser in " + new File(whereAmI.toURI()).getParentFile());
|
|
||||||
}
|
}
|
||||||
parser = path;
|
System.load(path.getAbsolutePath());
|
||||||
System.load(parser.getAbsolutePath());
|
} catch (NullPointerException | IllegalArgumentException | LinkageError e) {
|
||||||
} catch (IllegalArgumentException | URISyntaxException | LinkageError e) {
|
|
||||||
File root = new File(".").getAbsoluteFile();
|
|
||||||
if (!searchFromDirToTop(e, root, "target", "rust", "debug", name)) {
|
if (!searchFromDirToTop(e, root, "target", "rust", "debug", name)) {
|
||||||
throw new IllegalStateException("Cannot load parser from " + parser, e);
|
if (!searchFromDirToTop(
|
||||||
|
e, new File(".").getAbsoluteFile(), "target", "rust", "debug", name)) {
|
||||||
|
throw new IllegalStateException("Cannot load parser from " + root, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,48 +289,6 @@ public @interface Builtin {
|
|||||||
WrapException[] value() default {};
|
WrapException[] value() default {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Annotation approving implicit {@link
|
|
||||||
* com.oracle.truffle.api.TruffleLanguage#asGuestValue(Object)} translation done on the return
|
|
||||||
* object. The conversion is generated automatically, depending on the type of the value.
|
|
||||||
*
|
|
||||||
* <p>Note that while explicit translations to interop value are discouraged, we still want to
|
|
||||||
* occasionally support it to easy builtins-writing process. The presence of the {@link
|
|
||||||
* ReturningGuestObject} only ensures that it is intentional.
|
|
||||||
*
|
|
||||||
* <p>Consider a method returning an {@link java.io.OutputStream} which is not an interop value,
|
|
||||||
* for the sake of the example:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* class Foo {
|
|
||||||
* {@link Builtin.Method @Builtin.Method}
|
|
||||||
* {@link Builtin.ReturningGuestObject @Builtin.ReturningGuestObject}
|
|
||||||
* java.lang.OutputStream foo(Object item) {
|
|
||||||
* return // ...
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* The processor will detect the return type of method {@code foo} and perform an automatic
|
|
||||||
* conversion:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {@link BuiltinMethod @BuiltinMethod}(type = "Foo", name = "create")
|
|
||||||
* public class CreateFooNode extends Node {
|
|
||||||
* java.lang.Object execute(Foo self, Object item) {
|
|
||||||
* return context
|
|
||||||
* .asGuestValue(self.foo(item));
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* Without converting the object to the guest language value, it would crash during runtime.
|
|
||||||
* Without the presence of the annotation, the processor would detect the potential value
|
|
||||||
* requiring {@link com.oracle.truffle.api.TruffleLanguage#asGuestValue(Object)} translation but
|
|
||||||
* stop and report the error since it didn't seem to be intended by the user.
|
|
||||||
*/
|
|
||||||
@interface ReturningGuestObject {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Method marked with {@link Builtin.Specialize} annotation will generate specializations for
|
* A Method marked with {@link Builtin.Specialize} annotation will generate specializations for
|
||||||
* overloaded and non-overloaded methods. The annotation requires presence of {@link
|
* overloaded and non-overloaded methods. The annotation requires presence of {@link
|
||||||
|
@ -180,10 +180,6 @@ public class BuiltinsProcessor extends AbstractProcessor {
|
|||||||
|
|
||||||
OK:
|
OK:
|
||||||
if (!TypeWithKind.isValidGuestType(processingEnv, method.getReturnType())) {
|
if (!TypeWithKind.isValidGuestType(processingEnv, method.getReturnType())) {
|
||||||
if (method.getAnnotation(Builtin.ReturningGuestObject.class) != null) {
|
|
||||||
// guest objects can be of any type
|
|
||||||
break OK;
|
|
||||||
}
|
|
||||||
if (method.getAnnotation(SuppressWarnings.class) instanceof SuppressWarnings sw
|
if (method.getAnnotation(SuppressWarnings.class) instanceof SuppressWarnings sw
|
||||||
&& Arrays.asList(sw.value()).contains("generic-enso-builtin-type")) {
|
&& Arrays.asList(sw.value()).contains("generic-enso-builtin-type")) {
|
||||||
// assume the case was review
|
// assume the case was review
|
||||||
|
@ -105,8 +105,7 @@ public abstract class MethodGenerator {
|
|||||||
Kind.ERROR,
|
Kind.ERROR,
|
||||||
"Automatic conversion of value of type "
|
"Automatic conversion of value of type "
|
||||||
+ tpe.baseType()
|
+ tpe.baseType()
|
||||||
+ " to guest value requires explicit '@Builtin.ReturningGuestObject'"
|
+ " is no longer supported.");
|
||||||
+ " annotation");
|
|
||||||
}
|
}
|
||||||
return "Object";
|
return "Object";
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import java.util.List;
|
|||||||
import javax.annotation.processing.ProcessingEnvironment;
|
import javax.annotation.processing.ProcessingEnvironment;
|
||||||
import javax.lang.model.element.Element;
|
import javax.lang.model.element.Element;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import org.enso.interpreter.dsl.Builtin;
|
|
||||||
|
|
||||||
public abstract class MethodNodeClassGenerator {
|
public abstract class MethodNodeClassGenerator {
|
||||||
ClassName builtinNode;
|
ClassName builtinNode;
|
||||||
@ -29,7 +28,7 @@ public abstract class MethodNodeClassGenerator {
|
|||||||
* @return true if the annotation exists, false otherwise
|
* @return true if the annotation exists, false otherwise
|
||||||
*/
|
*/
|
||||||
protected boolean needsGuestValueConversion(Element origin) {
|
protected boolean needsGuestValueConversion(Element origin) {
|
||||||
return origin.getAnnotation(Builtin.ReturningGuestObject.class) != null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generate(
|
public void generate(
|
||||||
|
@ -41,9 +41,7 @@ public final class NoSpecializationClassGenerator extends MethodNodeClassGenerat
|
|||||||
processingEnvironment
|
processingEnvironment
|
||||||
.getMessager()
|
.getMessager()
|
||||||
.printMessage(
|
.printMessage(
|
||||||
Kind.ERROR,
|
Kind.ERROR, "Value is already TruffleObject, don't need any conversions", origin);
|
||||||
"Value is already TruffleObject, don't use @Builtin.ReturningGuestObject",
|
|
||||||
origin);
|
|
||||||
}
|
}
|
||||||
return new ExecuteMethodImplGenerator(
|
return new ExecuteMethodImplGenerator(
|
||||||
processingEnvironment, origin, asGuestValue, varArgExpansion);
|
processingEnvironment, origin, asGuestValue, varArgExpansion);
|
||||||
|
@ -38,14 +38,12 @@ public final class SpecializedMethodsGenerator extends MethodGenerator {
|
|||||||
elements,
|
elements,
|
||||||
first.getModifiers().contains(Modifier.STATIC),
|
first.getModifiers().contains(Modifier.STATIC),
|
||||||
first.getKind() == ElementKind.CONSTRUCTOR,
|
first.getKind() == ElementKind.CONSTRUCTOR,
|
||||||
first.getAnnotation(Builtin.ReturningGuestObject.class) != null,
|
false,
|
||||||
TypeWithKind.createFromTpe(first.getReturnType().toString()));
|
TypeWithKind.createFromTpe(first.getReturnType().toString()));
|
||||||
|
|
||||||
// Make sure all methods were defined the same way, except for paramters' types
|
// Make sure all methods were defined the same way, except for paramters' types
|
||||||
assert (allEqual(elements.stream().map(e -> e.getModifiers().contains(Modifier.STATIC))));
|
assert (allEqual(elements.stream().map(e -> e.getModifiers().contains(Modifier.STATIC))));
|
||||||
assert (allEqual(elements.stream().map(e -> e.getKind() == ElementKind.CONSTRUCTOR)));
|
assert (allEqual(elements.stream().map(e -> e.getKind() == ElementKind.CONSTRUCTOR)));
|
||||||
assert (allEqual(
|
|
||||||
elements.stream().map(e -> e.getAnnotation(Builtin.ReturningGuestObject.class) != null)));
|
|
||||||
assert (allEqual(
|
assert (allEqual(
|
||||||
elements.stream().map(e -> TypeWithKind.createFromTpe(e.getReturnType().toString()))));
|
elements.stream().map(e -> TypeWithKind.createFromTpe(e.getReturnType().toString()))));
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,84 @@ package org.enso.base;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class Stream_Utils {
|
public final class Stream_Utils {
|
||||||
|
private Stream_Utils() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conversion interface. Any Enso/Truffle object with invocable {@read} member that takes three
|
||||||
|
* arguments is eligible for being treated as host Java {@link InputStream}. There are two
|
||||||
|
* overloaded {@link #asInputStream conversion methods}. The <em>hosted Java interop</em> system
|
||||||
|
* of Truffle will pick the more suitable one depending on the type of argument.
|
||||||
|
*
|
||||||
|
* @see #asInputStream
|
||||||
|
*/
|
||||||
|
public static interface InputStreamLike {
|
||||||
|
public int read(byte[] arr, int off, int len) throws IOException;
|
||||||
|
|
||||||
|
public default int available() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No conversion conversion. When the argument is already {@link InputStream} there is no need for
|
||||||
|
* doing any further conversions.
|
||||||
|
*
|
||||||
|
* @param is
|
||||||
|
* @return the {@code is} itself
|
||||||
|
*/
|
||||||
|
public static InputStream asInputStream(InputStream is) {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conversion to {@link InputStream}. When the argument <em>looks like</em> an input stream, let's
|
||||||
|
* wrap it.
|
||||||
|
*
|
||||||
|
* @param inputStreamLike any guest object with {@code read} method
|
||||||
|
* @return proper
|
||||||
|
*/
|
||||||
|
public static InputStream asInputStream(InputStreamLike inputStreamLike) {
|
||||||
|
return new GuestInputStream(inputStreamLike);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conversion interface. Any Enso/Truffle object with invocable {@write} member that takes three
|
||||||
|
* arguments is eligible for being treated as host Java {@link OutputStream}. There are two
|
||||||
|
* overloaded {@link #asOutputStream conversion methods}. The <em>hosted Java interop</em> system
|
||||||
|
* of Truffle will pick the more suitable one depending on the type of argument.
|
||||||
|
*
|
||||||
|
* @see #asOutputStream
|
||||||
|
*/
|
||||||
|
public static interface OutputStreamLike {
|
||||||
|
public void write(byte[] arr, int off, int len) throws IOException;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No conversion conversion. When the argument is already {@link OutputStream} there is no need
|
||||||
|
* for doing any further conversions.
|
||||||
|
*
|
||||||
|
* @param os
|
||||||
|
* @return the {@code is} itself
|
||||||
|
*/
|
||||||
|
public static OutputStream asOutputStream(OutputStream os) {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conversion to {@link OutputStream}. When the argument <em>looks like</em> an output stream,
|
||||||
|
* let's wrap it.
|
||||||
|
*
|
||||||
|
* @param outputStreamLike any guest object with {@code write} method
|
||||||
|
* @return proper
|
||||||
|
*/
|
||||||
|
public static OutputStream asOutputStream(OutputStreamLike outputStreamLike) {
|
||||||
|
return new GuestOutputStream(outputStreamLike);
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] peek(InputStream stream, int n) throws IOException {
|
public static byte[] peek(InputStream stream, int n) throws IOException {
|
||||||
assert n >= 0;
|
assert n >= 0;
|
||||||
assert stream.markSupported();
|
assert stream.markSupported();
|
||||||
@ -25,4 +100,64 @@ public class Stream_Utils {
|
|||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class GuestInputStream extends InputStream {
|
||||||
|
private final InputStreamLike inputStreamLike;
|
||||||
|
|
||||||
|
private GuestInputStream(InputStreamLike inputStreamLike) {
|
||||||
|
this.inputStreamLike = inputStreamLike;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b, int off, int len) throws IOException {
|
||||||
|
return inputStreamLike.read(b, off, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
byte[] arr = new byte[1];
|
||||||
|
int read = read(arr, 0, 1);
|
||||||
|
if (read == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (read != 1) {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
return arr[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b) throws IOException {
|
||||||
|
return read(b, 0, b.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int available() throws IOException {
|
||||||
|
try {
|
||||||
|
return inputStreamLike.available();
|
||||||
|
} catch (Error | Exception e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class GuestOutputStream extends OutputStream {
|
||||||
|
|
||||||
|
private final OutputStreamLike outputStreamLike;
|
||||||
|
|
||||||
|
private GuestOutputStream(OutputStreamLike os) {
|
||||||
|
this.outputStreamLike = os;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
byte[] arr = new byte[] {(byte) b};
|
||||||
|
write(arr, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(byte[] b, int off, int len) throws IOException {
|
||||||
|
outputStreamLike.write(b, off, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
package org.enso.base;
|
package org.enso.base;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.StringReader;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import org.w3c.dom.DOMConfiguration;
|
import org.w3c.dom.DOMConfiguration;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
|
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
|
||||||
@ -10,6 +16,7 @@ import org.w3c.dom.ls.DOMImplementationLS;
|
|||||||
import org.w3c.dom.ls.LSOutput;
|
import org.w3c.dom.ls.LSOutput;
|
||||||
import org.w3c.dom.ls.LSSerializer;
|
import org.w3c.dom.ls.LSSerializer;
|
||||||
import org.xml.sax.ErrorHandler;
|
import org.xml.sax.ErrorHandler;
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.xml.sax.SAXParseException;
|
import org.xml.sax.SAXParseException;
|
||||||
|
|
||||||
@ -62,7 +69,25 @@ public class XML_Utils {
|
|||||||
return out.toString();
|
return out.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setCustomErrorHandler(DocumentBuilder documentBuilder) {
|
public static Document parseStream(InputStream is)
|
||||||
|
throws ParserConfigurationException, SAXException, IOException {
|
||||||
|
return doParse(new InputSource(is));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Document parseString(String text)
|
||||||
|
throws ParserConfigurationException, SAXException, IOException {
|
||||||
|
return doParse(new InputSource(new StringReader(text)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Document doParse(InputSource is)
|
||||||
|
throws ParserConfigurationException, SAXException, IOException {
|
||||||
|
var factory = DocumentBuilderFactory.newInstance();
|
||||||
|
var builder = factory.newDocumentBuilder();
|
||||||
|
configureErrorHandler(builder);
|
||||||
|
return builder.parse(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void configureErrorHandler(DocumentBuilder documentBuilder) {
|
||||||
documentBuilder.setErrorHandler(
|
documentBuilder.setErrorHandler(
|
||||||
new ErrorHandler() {
|
new ErrorHandler() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package org.enso.base.file_system;
|
||||||
|
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.PathMatcher;
|
||||||
|
|
||||||
|
public final class File_Utils {
|
||||||
|
private File_Utils() {}
|
||||||
|
|
||||||
|
public static Path toPath(String path) {
|
||||||
|
return Path.of(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PathMatcher matchPath(String filter) {
|
||||||
|
var fs = FileSystems.getDefault();
|
||||||
|
var matcher = fs.getPathMatcher(filter);
|
||||||
|
return matcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean matches(PathMatcher matcher, String pathStr) {
|
||||||
|
return matcher.matches(Path.of(pathStr));
|
||||||
|
}
|
||||||
|
}
|
@ -5,8 +5,8 @@ import Standard.Base.Errors.No_Such_Key.No_Such_Key
|
|||||||
from Standard.Test import all
|
from Standard.Test import all
|
||||||
|
|
||||||
|
|
||||||
polyglot java import java.nio.file.Path as JavaPath
|
|
||||||
polyglot java import java.util.Map as JavaMap
|
polyglot java import java.util.Map as JavaMap
|
||||||
|
polyglot java import org.enso.base.file_system.File_Utils
|
||||||
|
|
||||||
## Type that violates reflexivity
|
## Type that violates reflexivity
|
||||||
type My_Nan
|
type My_Nan
|
||||||
@ -105,7 +105,7 @@ add_specs suite_builder =
|
|||||||
empty_map_fn = entry.get 1
|
empty_map_fn = entry.get 1
|
||||||
pending = entry.get 2
|
pending = entry.get 2
|
||||||
add_common_specs suite_builder lang pending empty_map_fn
|
add_common_specs suite_builder lang pending empty_map_fn
|
||||||
|
|
||||||
suite_builder.group "Enso maps" group_builder->
|
suite_builder.group "Enso maps" group_builder->
|
||||||
|
|
||||||
|
|
||||||
@ -278,11 +278,11 @@ add_specs suite_builder =
|
|||||||
map.get (js_str "A") . should_equal 42
|
map.get (js_str "A") . should_equal 42
|
||||||
|
|
||||||
group_builder.specify "should support host objects as keys" <|
|
group_builder.specify "should support host objects as keys" <|
|
||||||
# JavaPath has proper implementation of hashCode
|
# java.nio.path.Path has proper implementation of hashCode
|
||||||
map = Map.singleton (JavaPath.of "/home/user/file.txt") 42
|
map = Map.singleton (File_Utils.toPath "/home/user/file.txt") 42
|
||||||
map.get "X" . should_equal Nothing
|
map.get "X" . should_equal Nothing
|
||||||
map.get "A" . should_equal Nothing
|
map.get "A" . should_equal Nothing
|
||||||
map.get (JavaPath.of "/home/user/file.txt") . should_equal 42
|
map.get (File_Utils.toPath "/home/user/file.txt") . should_equal 42
|
||||||
|
|
||||||
group_builder.specify "should support Python objects as keys" pending=pending_python_missing <|
|
group_builder.specify "should support Python objects as keys" pending=pending_python_missing <|
|
||||||
py_obj = py_wrapper 42
|
py_obj = py_wrapper 42
|
||||||
@ -464,14 +464,14 @@ add_common_specs suite_builder prefix:Text (pending : (Text | Nothing)) (empty_m
|
|||||||
suite_builder.group prefix+": Common polyglot Map operations" pending=pending group_builder->
|
suite_builder.group prefix+": Common polyglot Map operations" pending=pending group_builder->
|
||||||
group_builder.specify "should get the default comparator for polyglot maps" <|
|
group_builder.specify "should get the default comparator for polyglot maps" <|
|
||||||
Comparable.from empty_map . should_equal Default_Comparator
|
Comparable.from empty_map . should_equal Default_Comparator
|
||||||
|
|
||||||
group_builder.specify "should compare two hash maps" <|
|
group_builder.specify "should compare two hash maps" <|
|
||||||
(empty_map.insert "a" 1).should_equal (empty_map.insert "a" 1)
|
(empty_map.insert "a" 1).should_equal (empty_map.insert "a" 1)
|
||||||
(empty_map.insert "b" 2).should_not_equal (empty_map.insert "a" 1)
|
(empty_map.insert "b" 2).should_not_equal (empty_map.insert "a" 1)
|
||||||
empty_map.should_equal empty_map
|
empty_map.should_equal empty_map
|
||||||
empty_map.should_not_equal (empty_map.insert "a" 1)
|
empty_map.should_not_equal (empty_map.insert "a" 1)
|
||||||
(empty_map.insert "a" 1 . insert "b" 2).should_equal (empty_map.insert "b" 2 . insert "a" 1)
|
(empty_map.insert "a" 1 . insert "b" 2).should_equal (empty_map.insert "b" 2 . insert "a" 1)
|
||||||
|
|
||||||
group_builder.specify "should allow checking for non emptiness" <|
|
group_builder.specify "should allow checking for non emptiness" <|
|
||||||
non_empty = empty_map . insert "foo" 1234
|
non_empty = empty_map . insert "foo" 1234
|
||||||
empty_map.not_empty . should_be_false
|
empty_map.not_empty . should_be_false
|
||||||
@ -481,7 +481,7 @@ add_common_specs suite_builder prefix:Text (pending : (Text | Nothing)) (empty_m
|
|||||||
non_empty = empty_map.insert "a" "b" . insert "x" "y"
|
non_empty = empty_map.insert "a" "b" . insert "x" "y"
|
||||||
empty_map.size . should_equal 0
|
empty_map.size . should_equal 0
|
||||||
non_empty.size . should_equal 2
|
non_empty.size . should_equal 2
|
||||||
|
|
||||||
group_builder.specify "should allow checking for emptiness" <|
|
group_builder.specify "should allow checking for emptiness" <|
|
||||||
non_empty = empty_map . insert "foo" 1234
|
non_empty = empty_map . insert "foo" 1234
|
||||||
empty_map.is_empty . should_be_true
|
empty_map.is_empty . should_be_true
|
||||||
@ -558,7 +558,11 @@ add_common_specs suite_builder prefix:Text (pending : (Text | Nothing)) (empty_m
|
|||||||
empty_map.insert Nothing 1 . insert Nothing 2 . get Nothing . should_equal 2
|
empty_map.insert Nothing 1 . insert Nothing 2 . get Nothing . should_equal 2
|
||||||
empty_map.insert Nothing 1 . should_equal (empty_map.insert Nothing 1)
|
empty_map.insert Nothing 1 . should_equal (empty_map.insert Nothing 1)
|
||||||
empty_map.insert Nothing 1 . insert Nothing 2 . at Nothing . should_equal 2
|
empty_map.insert Nothing 1 . insert Nothing 2 . at Nothing . should_equal 2
|
||||||
|
|
||||||
|
group_builder.specify "should handle JavaScript null as keys" <|
|
||||||
empty_map.insert js_null 1 . at Nothing . should_equal 1
|
empty_map.insert js_null 1 . at Nothing . should_equal 1
|
||||||
|
|
||||||
|
group_builder.specify "should handle Python None as keys" pending=pending_python_missing <|
|
||||||
empty_map.insert py_none 1 . at Nothing . should_equal 1
|
empty_map.insert py_none 1 . at Nothing . should_equal 1
|
||||||
|
|
||||||
group_builder.specify "should define a well-defined text conversion" <|
|
group_builder.specify "should define a well-defined text conversion" <|
|
||||||
|
@ -85,6 +85,7 @@ import project.Runtime.Stack_Traces_Spec
|
|||||||
import project.System.Environment_Spec
|
import project.System.Environment_Spec
|
||||||
import project.System.File_Spec
|
import project.System.File_Spec
|
||||||
import project.System.File_Read_Spec
|
import project.System.File_Read_Spec
|
||||||
|
import project.System.Input_Stream_Spec
|
||||||
import project.System.Process_Spec
|
import project.System.Process_Spec
|
||||||
import project.System.Reporting_Stream_Decoder_Spec
|
import project.System.Reporting_Stream_Decoder_Spec
|
||||||
import project.System.Reporting_Stream_Encoder_Spec
|
import project.System.Reporting_Stream_Encoder_Spec
|
||||||
@ -112,6 +113,7 @@ main filter=Nothing =
|
|||||||
File_Spec.add_specs suite_builder
|
File_Spec.add_specs suite_builder
|
||||||
Temporary_File_Spec.add_specs suite_builder
|
Temporary_File_Spec.add_specs suite_builder
|
||||||
File_Read_Spec.add_specs suite_builder
|
File_Read_Spec.add_specs suite_builder
|
||||||
|
Input_Stream_Spec.add_specs suite_builder
|
||||||
Reporting_Stream_Decoder_Spec.add_specs suite_builder
|
Reporting_Stream_Decoder_Spec.add_specs suite_builder
|
||||||
Reporting_Stream_Encoder_Spec.add_specs suite_builder
|
Reporting_Stream_Encoder_Spec.add_specs suite_builder
|
||||||
Http_Header_Spec.add_specs suite_builder
|
Http_Header_Spec.add_specs suite_builder
|
||||||
|
@ -5,8 +5,8 @@ from Standard.Test import all
|
|||||||
|
|
||||||
|
|
||||||
polyglot java import java.math.BigInteger as Java_Big_Integer
|
polyglot java import java.math.BigInteger as Java_Big_Integer
|
||||||
polyglot java import java.nio.file.Path as Java_Path
|
|
||||||
polyglot java import java.util.Random as Java_Random
|
polyglot java import java.util.Random as Java_Random
|
||||||
|
polyglot java import org.enso.base.file_system.File_Utils
|
||||||
polyglot java import org.enso.base_test_helpers.IntHolder
|
polyglot java import org.enso.base_test_helpers.IntHolder
|
||||||
polyglot java import org.enso.base_test_helpers.IntHolderEquals
|
polyglot java import org.enso.base_test_helpers.IntHolderEquals
|
||||||
|
|
||||||
@ -180,8 +180,8 @@ add_specs suite_builder =
|
|||||||
((CustomEqType.C1 0) == (CustomEqType.C2 7 3)).should_be_false
|
((CustomEqType.C1 0) == (CustomEqType.C2 7 3)).should_be_false
|
||||||
|
|
||||||
group_builder.specify "should dispatch to equals on host values" <|
|
group_builder.specify "should dispatch to equals on host values" <|
|
||||||
path1 = Java_Path.of "home" "user" . resolve "file.txt"
|
path1 = File_Utils.toPath "home" . resolve "user" . resolve "file.txt"
|
||||||
path2 = Java_Path.of "home" "user" "file.txt"
|
path2 = File_Utils.toPath "home" . resolve "user" . resolve "file.txt"
|
||||||
(path1 == path2).should_be_true
|
(path1 == path2).should_be_true
|
||||||
path3 = path1.resolve "subfile.txt"
|
path3 = path1.resolve "subfile.txt"
|
||||||
(path3 == path2).should_be_false
|
(path3 == path2).should_be_false
|
||||||
|
@ -6,12 +6,33 @@ import Standard.Base.System.Input_Stream.Input_Stream
|
|||||||
from Standard.Test import all
|
from Standard.Test import all
|
||||||
|
|
||||||
polyglot java import org.enso.base_test_helpers.RangeStream
|
polyglot java import org.enso.base_test_helpers.RangeStream
|
||||||
|
polyglot java import org.enso.base.Stream_Utils
|
||||||
|
|
||||||
main filter=Nothing =
|
main filter=Nothing =
|
||||||
suite = Test.build suite_builder->
|
suite = Test.build suite_builder->
|
||||||
add_specs suite_builder
|
add_specs suite_builder
|
||||||
suite.run_with_filter filter
|
suite.run_with_filter filter
|
||||||
|
|
||||||
|
|
||||||
|
foreign js is_like data available = """
|
||||||
|
let at = 0
|
||||||
|
let is = {
|
||||||
|
read : function(arr, off, len) {
|
||||||
|
let cnt = 0;
|
||||||
|
while (len-- > 0) {
|
||||||
|
arr[off++] = data[at++];
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (available) {
|
||||||
|
is.available = function() {
|
||||||
|
return data.length - at;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return is;
|
||||||
|
|
||||||
add_specs suite_builder = suite_builder.group "Input Stream" group_builder->
|
add_specs suite_builder = suite_builder.group "Input Stream" group_builder->
|
||||||
group_builder.specify "should be peekable if backed by memory" <|
|
group_builder.specify "should be peekable if backed by memory" <|
|
||||||
Managed_Resource.bracket (Input_Stream.from_bytes [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) (.close) stream->
|
Managed_Resource.bracket (Input_Stream.from_bytes [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) (.close) stream->
|
||||||
@ -61,3 +82,33 @@ add_specs suite_builder = suite_builder.group "Input Stream" group_builder->
|
|||||||
promoted_stream.peek_bytes 10 . should_equal [100, 101, 102, 103, 104]
|
promoted_stream.peek_bytes 10 . should_equal [100, 101, 102, 103, 104]
|
||||||
# The read still succeeds - ensuring there isn't some early EOF
|
# The read still succeeds - ensuring there isn't some early EOF
|
||||||
promoted_stream.read_n_bytes 10 . should_equal [100, 101, 102, 103, 104]
|
promoted_stream.read_n_bytes 10 . should_equal [100, 101, 102, 103, 104]
|
||||||
|
|
||||||
|
group_builder.specify "read without available" <|
|
||||||
|
stream_like = is_like [20, 5, 1, 10] False
|
||||||
|
is = Stream_Utils.asInputStream stream_like
|
||||||
|
is.available . should_equal 0
|
||||||
|
|
||||||
|
is.read . should_equal 20
|
||||||
|
is.read . should_equal 5
|
||||||
|
|
||||||
|
is.available . should_equal 0
|
||||||
|
|
||||||
|
is.read . should_equal 1
|
||||||
|
is.read . should_equal 10
|
||||||
|
|
||||||
|
is.available . should_equal 0
|
||||||
|
|
||||||
|
group_builder.specify "read with available" <|
|
||||||
|
stream_like = is_like [20, 6, 8, 23] True
|
||||||
|
is = Stream_Utils.asInputStream stream_like
|
||||||
|
is.available . should_equal 4
|
||||||
|
|
||||||
|
is.read . should_equal 20
|
||||||
|
is.read . should_equal 6
|
||||||
|
|
||||||
|
is.available . should_equal 2
|
||||||
|
|
||||||
|
is.read . should_equal 8
|
||||||
|
is.read . should_equal 23
|
||||||
|
|
||||||
|
is.available . should_equal 0
|
||||||
|
Loading…
Reference in New Issue
Block a user