Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getPublicTruffleFile may yield an exception #10380

Merged
merged 1 commit into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.enso.interpreter.runtime.data.vector.ArrayLikeAtNode;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.data.vector.ArrayLikeLengthNode;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;

Expand Down Expand Up @@ -451,7 +452,12 @@ private static FileSystemException replaceCreateDirectoriesNoSuchFileException(
return noSuchFileException;
}

var parent = fromString(EnsoContext.get(null), path).truffleFile.getParent();
var parent =
switch (fromString(EnsoContext.get(null), path)) {
case EnsoFile f -> f.truffleFile.getParent();
case null -> null;
default -> null;
};
// Unknown parent, so the heuristic cannot be applied - return the original.
if (parent == null) {
return noSuchFileException;
Expand Down Expand Up @@ -486,7 +492,12 @@ private static FileSystemException replaceCreateDirectoriesGenericException(
// On Linux, when creating a directory tree `foo/my-file.txt/a/b/c`, the operation fails with
// `FileSystemException` with the full path (`foo/my-file.txt/a/b/c`). So we need to traverse
// this path to find the actually problematic part.
var file = fromString(EnsoContext.get(null), path).truffleFile;
var file =
switch (fromString(EnsoContext.get(null), path)) {
case EnsoFile f -> f.truffleFile;
case null -> null;
default -> null;
};
// We try to find the first file that exists on the path.
while (file != null && !file.exists()) {
file = file.getParent();
Expand Down Expand Up @@ -630,9 +641,19 @@ public boolean startsWith(EnsoFile parent) {
autoRegister = false)
@Builtin.Specialize
@TruffleBoundary
public static EnsoFile fromString(EnsoContext context, String path) {
TruffleFile file = context.getPublicTruffleFile(path);
return new EnsoFile(file);
public static EnsoObject fromString(EnsoContext context, String path)
throws IllegalArgumentException {
try {
TruffleFile file = context.getPublicTruffleFile(path);
return new EnsoFile(file);
} catch (IllegalArgumentException | UnsupportedOperationException ex) {
var err =
context
.getBuiltins()
.error()
.makeUnsupportedArgumentsError(new Object[] {Text.create(path)}, ex.getMessage());
return DataflowError.withoutTrace(err, null);
}
}

@Builtin.Method(
Expand All @@ -652,7 +673,7 @@ public static EnsoFile currentDirectory(EnsoContext context) {
autoRegister = false)
@Builtin.Specialize
@TruffleBoundary
public static EnsoFile userHome(EnsoContext context) {
public static EnsoObject userHome(EnsoContext context) {
return fromString(context, System.getProperty("user.home"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.oracle.truffle.api.nodes.Node;
import java.util.Objects;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
Expand All @@ -24,7 +25,7 @@
*/
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(TypesLibrary.class)
public final class DataflowError extends AbstractTruffleException {
public final class DataflowError extends AbstractTruffleException implements EnsoObject {
/** Signals (local) values that haven't yet been initialized */
public static final DataflowError UNINITIALIZED = new DataflowError(null, (Node) null);

Expand Down
9 changes: 9 additions & 0 deletions test/Base_Tests/src/System/File_Spec.enso
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from Standard.Base import all
import Standard.Base.Errors.Common.Forbidden_Operation
import Standard.Base.Errors.Common.Dry_Run_Operation
import Standard.Base.Errors.Common.Unsupported_Argument_Types
import Standard.Base.Errors.Encoding_Error.Encoding_Error
import Standard.Base.Errors.File_Error.File_Error
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
Expand Down Expand Up @@ -31,6 +32,10 @@ add_specs suite_builder =
windows_file = enso_project.data / "windows.txt"
non_existent_file = File.new "does_not_exist.txt"

only_on_windows = case Platform.os of
Platform.OS.Windows -> Nothing
_ -> "This test runs only on Windows."

suite_builder.group "File Operations" group_builder->
group_builder.specify "should get name of the root" <|
root = File.new "/"
Expand All @@ -41,6 +46,10 @@ add_specs suite_builder =
path = sample_file.path
File.new path

group_builder.specify "invalid character in path on Windows" pending=only_on_windows <|
err = File.new "C:\dev:a"
err . should_fail_with Unsupported_Argument_Types

group_builder.specify "should have `new` be a no-op on a file" <|
file = File.new sample_file
file . should_equal sample_file
Expand Down
Loading