From 3379ce51f2bdfb143ca302b90997efc73dec43bd Mon Sep 17 00:00:00 2001 From: Hubert Plociniczak Date: Mon, 9 Jan 2023 11:35:36 +0100 Subject: [PATCH] Report failed name resolutions in type signatures (#4030) Compiler performed name resolution of literals in type signatures but would silently fail to report any problems. This meant that wrong names or forgotten imports would sneak in to stdlib. This change introduces 2 main changes: 1) failed name resolutions are appended in `TypeNames` pass 2) `GatherDiagnostics` pass also collects and reports failures from type signatures IR Updated stdlib so that it passes given the correct gatekeepers in place. --- CHANGELOG.md | 2 + .../lib/Standard/Base/0.0.0-dev/src/Data.enso | 1 + .../Base/0.0.0-dev/src/Data/Numbers.enso | 6 +- .../0.0.0-dev/src/Data/Text/Extensions.enso | 10 +- .../0.0.0-dev/src/Data/Text/Regex/Engine.enso | 1 + .../src/Data/Text/Regex/Pattern.enso | 1 + .../0.0.0-dev/src/Data/Time/Duration.enso | 1 + .../Standard/Base/0.0.0-dev/src/Error.enso | 1 + .../Standard/Base/0.0.0-dev/src/Runtime.enso | 7 + .../Base/0.0.0-dev/src/System/File.enso | 2 + .../src/Connection/SQLite_Options.enso | 2 +- .../Database/0.0.0-dev/src/Data/Dialect.enso | 2 + .../Database/0.0.0-dev/src/Data/Table.enso | 8 +- .../0.0.0-dev/src/Internal/Helpers.enso | 1 + .../Image/0.0.0-dev/src/Data/Image.enso | 2 + .../Table/0.0.0-dev/src/Data/Storage.enso | 2 + .../Table/0.0.0-dev/src/Data/Table.enso | 5 +- .../0.0.0-dev/src/Excel/Excel_Reader.enso | 1 + .../0.0.0-dev/src/Excel/Excel_Writer.enso | 2 +- .../0.0.0-dev/src/Internal/Table_Helpers.enso | 3 +- .../Test/0.0.0-dev/src/Suite_Config.enso | 1 + .../0.0.0-dev/src/Scatter_Plot.enso | 4 +- .../0.0.0-dev/src/Table/Visualization.enso | 2 +- .../pass/analyse/GatherDiagnostics.scala | 16 +- .../compiler/pass/resolve/TypeNames.scala | 26 ++- .../pass/resolve/TypeSignatures.scala | 6 +- .../test/pass/resolve/TypeNamesTest.scala | 174 ++++++++++++++++++ .../pass/resolve/TypeSignaturesTest.scala | 2 +- .../test/semantic/TypeSignaturesTest.scala | 8 + .../test/semantic/IOContextTest.scala | 4 + test/Tests/src/Semantic/Equals_Spec.enso | 1 + test/Tests/src/Semantic/Runtime_Spec.enso | 7 +- .../Standard/Base/0.0.0-dev/src/Runtime.enso | 4 + 33 files changed, 280 insertions(+), 35 deletions(-) create mode 100644 engine/runtime/src/test/scala/org/enso/compiler/test/pass/resolve/TypeNamesTest.scala diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b82b88b64..86dc732a78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -498,6 +498,7 @@ - [IGV can jump to JMH sources & more][4008] - [Basic support of VSCode integration][4014] - [Sync language server with file system after VCS restore][4020] +- [Report failures in name resolution in type signatures][4030] [3227]: https://github.com/enso-org/enso/pull/3227 [3248]: https://github.com/enso-org/enso/pull/3248 @@ -579,6 +580,7 @@ [4008]: https://github.com/enso-org/enso/pull/4008 [4014]: https://github.com/enso-org/enso/pull/4014 [4020]: https://github.com/enso-org/enso/pull/4020 +[4030]: https://github.com/enso-org/enso/pull/4030 # Enso 2.0.0-alpha.18 (2021-10-12) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso index 39184b2e67..a5fa9a84d0 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso @@ -7,6 +7,7 @@ import project.Error.Common.Type_Error import project.Error.Error import project.Error.File_Error.File_Error import project.Error.Problem_Behavior.Problem_Behavior +import project.Network.URI.URI import project.Network.HTTP.Header.Header import project.Network.HTTP.HTTP import project.Network.HTTP.HTTP_Method.HTTP_Method diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso index 3e91768fe4..7e639fb38b 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso @@ -577,7 +577,7 @@ type Decimal ## ALIAS From Text Parses a textual representation of a decimal into a decimal number, returning - a `Parse_Error` if the text does not represent a valid decimal. + a `Number_Parse_Error` if the text does not represent a valid decimal. Arguments: - text: The text to parse into a decimal. @@ -587,7 +587,7 @@ type Decimal Parse the text "7.6" into a decimal number. Decimal.parse "7.6" - parse : Text -> Locale | Nothing -> Decimal ! Parse_Error + parse : Text -> Locale | Nothing -> Decimal ! Number_Parse_Error parse text locale=Nothing = case locale of Nothing -> Panic.catch NumberFormatException (Double.parseDouble text) _-> Error.throw (Number_Parse_Error.Error text) @@ -945,7 +945,7 @@ type Integer ## ALIAS From Text Parses a textual representation of an integer into an integer number, returning - a `Parse_Error` if the text does not represent a valid integer. + a `Number_Parse_Error` if the text does not represent a valid integer. Arguments: - text: The text to parse into a integer. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Extensions.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Extensions.enso index 1de9d4ee89..eca04047b1 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Extensions.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Extensions.enso @@ -19,6 +19,7 @@ import project.Data.Text.Span.Utf_16_Span import project.Data.Text.Text import project.Data.Text.Text_Matcher.Text_Matcher import project.Data.Text.Text_Sub_Range.Codepoint_Ranges +import project.Data.Text.Text_Sub_Range.Text_Sub_Range import project.Data.Vector.Vector import project.Error.Common.Compile_Error import project.Error.Common.Index_Out_Of_Bounds @@ -30,6 +31,7 @@ import project.Meta import project.Nothing.Nothing from project.Data.Boolean import Boolean, True, False +from project.Data.Text.Text_Sub_Range import Codepoint_Ranges, Text_Sub_Range import project.Data.Index_Sub_Range as Index_Sub_Range_Module @@ -523,7 +525,7 @@ Text.is_whitespace self = Get the ASCII bytes of the text "Hello". "Hello".bytes (Encoding.ascii) -Text.bytes : Encoding -> Problem_Behavior -> Vector Byte +Text.bytes : Encoding -> Problem_Behavior -> Vector Integer Text.bytes self encoding on_problems=Problem_Behavior.Report_Warning = result = Encoding_Utils.get_bytes self (encoding . to_java_charset) vector = Vector.from_polyglot_array result.result @@ -546,7 +548,7 @@ Text.bytes self encoding on_problems=Problem_Behavior.Report_Warning = Get the ASCII bytes of the text "Hello". "Hello".bytes (Encoding.ascii) -Text.from_bytes : Vector Byte -> Encoding -> Problem_Behavior -> Text +Text.from_bytes : Vector Integer -> Encoding -> Problem_Behavior -> Text Text.from_bytes bytes encoding on_problems=Problem_Behavior.Report_Warning = result = Encoding_Utils.from_bytes bytes.to_array (encoding . to_java_charset) if result.warnings.is_nothing then result.result else @@ -569,7 +571,7 @@ Text.from_bytes bytes encoding on_problems=Problem_Behavior.Report_Warning = Get the UTF-8 bytes of the text "Hello". "Hello".utf_8 -Text.utf_8 : Problem_Behavior -> Vector Byte +Text.utf_8 : Problem_Behavior -> Vector Integer Text.utf_8 self on_problems=Problem_Behavior.Report_Warning = self.bytes Encoding.utf_8 on_problems @@ -590,7 +592,7 @@ Text.utf_8 self on_problems=Problem_Behavior.Report_Warning = Decoding the bytes to get a text. Text.from_utf_8 [-32, -92, -107, -32, -91, -115, -32, -92, -73, -32, -92, -65] -Text.from_utf_8 : Vector Byte -> Problem_Behavior -> Text +Text.from_utf_8 : Vector Integer -> Problem_Behavior -> Text Text.from_utf_8 bytes on_problems=Problem_Behavior.Report_Warning = Text.from_bytes bytes Encoding.utf_8 on_problems diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Engine.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Engine.enso index 3f91523e6c..21684024b6 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Engine.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Engine.enso @@ -19,6 +19,7 @@ import project.Data.Text.Text import project.Data.Text.Regex.Regex_Option.Regex_Option import project.Data.Text.Regex.Invalid_Option +import project.Data.Text.Regex.Pattern.Pattern import project.Data.Vector.Vector import project.Error.Common.Compile_Error import project.Error.Unimplemented.Unimplemented diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso index 6805ad9f69..e59066cf5b 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso @@ -1,6 +1,7 @@ import project.Data.Boolean.Boolean import project.Data.Numbers.Integer import project.Data.Text.Matching_Mode +import project.Data.Text.Regex.Match.Match import project.Data.Text.Regex.Regex_Mode.Regex_Mode import project.Data.Text.Text import project.Data.Vector.Vector diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Duration.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Duration.enso index 9eb0008321..1c7415dfa4 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Duration.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Duration.enso @@ -1,5 +1,6 @@ import project.Any.Any import project.Data.Json.JS_Object +import project.Data.Numbers.Decimal import project.Data.Numbers.Integer import project.Data.Ordering.Ordering import project.Data.Pair.Pair diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Error.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Error.enso index 283a13c9c3..71e5823f9e 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Error.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Error.enso @@ -1,5 +1,6 @@ import project.Any.Any import project.Data.Text.Text +import project.Data.Vector.Vector import project.Meta import project.Panic.Panic import project.Runtime.Stack_Trace_Element diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso index 03c6a7aec7..aeefa4fa3b 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso @@ -97,6 +97,13 @@ type Stack_Trace_Element ## PRIVATE Value name source_location +## ADVANCED + + Types indicating allowed IO operations +type IO_Permissions + Input + Output + ## ADVANCED UNSTABLE diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso index 7e6685da83..a32bc62898 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso @@ -26,6 +26,8 @@ import project.System.File.File_Permissions.File_Permissions from project.Data.Boolean import Boolean, True, False polyglot java import org.enso.base.Encoding_Utils +polyglot java import org.enso.base.encoding.ReportingStreamDecoder +polyglot java import org.enso.base.encoding.ReportingStreamEncoder polyglot java import java.io.InputStream as Java_Input_Stream polyglot java import java.io.OutputStream as Java_Output_Stream polyglot java import java.nio.file.FileSystems diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/SQLite_Options.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/SQLite_Options.enso index 17a14c213e..f862b65a0b 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/SQLite_Options.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/SQLite_Options.enso @@ -1,6 +1,6 @@ from Standard.Base import all -import project.Connection.Connection_Options +import project.Connection.Connection_Options.Connection_Options import project.Internal.SQLite.SQLite_Connection type SQLite_Options diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Dialect.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Dialect.enso index 02c6731d55..104117ad81 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Dialect.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Dialect.enso @@ -7,8 +7,10 @@ import project.Connection.Connection.Connection import project.Data.SQL_Statement.SQL_Statement import project.Data.SQL_Type.SQL_Type import project.Data.Table.Table +import project.Internal.IR.From_Spec.From_Spec import project.Internal.IR.Internal_Column.Internal_Column import project.Internal.IR.Order_Descriptor.Order_Descriptor +import project.Internal.IR.Query.Query import project.Internal.Postgres.Postgres_Dialect import project.Internal.Redshift.Redshift_Dialect import project.Internal.SQLite.SQLite_Dialect diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso index fb3645c16a..a9f9f7d330 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso @@ -8,10 +8,12 @@ import Standard.Base.Error.Incomparable_Values.Incomparable_Values import Standard.Base.Error.Unimplemented.Unimplemented from Standard.Table import Auto_Detect, Aggregate_Column, Data_Formatter, Column_Name_Mapping, Column_Selector, Sort_Column_Selector, Sort_Column, Match_Columns, Position +import Standard.Table.Data.Column_Type_Selection.Column_Type_Selection import Standard.Table.Data.Expression.Expression import Standard.Table.Data.Expression.Expression_Error import Standard.Table.Data.Join_Condition.Join_Condition import Standard.Table.Data.Join_Kind.Join_Kind +import Standard.Table.Data.Row.Row import Standard.Table.Data.Table.Table as Materialized_Table import Standard.Table.Internal.Java_Exports import Standard.Table.Internal.Table_Helpers @@ -21,7 +23,7 @@ import Standard.Table.Internal.Aggregate_Column_Helper from Standard.Table.Data.Column import get_item_string from Standard.Table.Data.Table import print_table from Standard.Table.Internal.Filter_Condition_Helpers import make_filter_column -from Standard.Table.Errors import No_Index_Set_Error, No_Such_Column +from Standard.Table.Errors import Column_Count_Mismatch, No_Index_Set_Error, No_Such_Column import project.Data.Column.Column import project.Data.SQL_Statement.SQL_Statement @@ -1065,7 +1067,7 @@ type Table invalid, a `File_Error.Not_Found` is raised. - If another IO error occurs, such as access denied, an `File_Error.IO_Error` is raised. - - If appending and the columns do not match, a `Column_Mismatch` is + - If appending and the columns do not match, a `Column_Count_Mismatch` is raised. - Other specific errors or warnings that can be raised depend on the format argument. @@ -1091,7 +1093,7 @@ type Table connection = Database.connect (SQLite (File.new "db.sqlite")) table = connection.query (SQL_Query.Table_Name "Table") table.write (enso_project.data / "example_csv_output.csv") - write : File|Text -> File_Format -> Existing_File_Behavior -> Match_Columns -> Problem_Behavior -> Nothing ! Column_Mismatch | Illegal_Argument | File_Error + write : File|Text -> File_Format -> Existing_File_Behavior -> Match_Columns -> Problem_Behavior -> Nothing ! Column_Count_Mismatch | Illegal_Argument | File_Error write self path format=Auto_Detect on_existing_file=Existing_File_Behavior.Backup match_columns=Match_Columns.By_Name on_problems=Report_Warning = # TODO This should ideally be done in a streaming manner, or at least respect the row limits. self.read.write path format on_existing_file match_columns on_problems diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Helpers.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Helpers.enso index dc709292aa..55f42fc8ad 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Helpers.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Helpers.enso @@ -2,6 +2,7 @@ from Standard.Base import all import project.Data.Table.Table import project.Data.Column.Column +import project.Internal.IR.Internal_Column.Internal_Column from project.Errors import Unsupported_Name, Unsupported_Database_Operation diff --git a/distribution/lib/Standard/Image/0.0.0-dev/src/Data/Image.enso b/distribution/lib/Standard/Image/0.0.0-dev/src/Data/Image.enso index 56249b2539..863e567379 100644 --- a/distribution/lib/Standard/Image/0.0.0-dev/src/Data/Image.enso +++ b/distribution/lib/Standard/Image/0.0.0-dev/src/Data/Image.enso @@ -1,6 +1,8 @@ from Standard.Base import all import Standard.Base.Error.File_Error.File_Error +import project.Read_Flag.Read_Flag +import project.Write_Flag.Write_Flag import project.Data.Histogram.Histogram import project.Data.Matrix.Matrix import project.Data.Matrix_Error.Matrix_Error diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Storage.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Storage.enso index 8ff357e68c..f3cf956735 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Storage.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Storage.enso @@ -1,3 +1,5 @@ +import Standard.Base.Data.Vector.Vector + ## Represents different types of underlying storage for Columns. type Storage ## A column storing text data. diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso index 654fda25da..ed8597933d 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso @@ -18,6 +18,7 @@ import project.Data.Join_Condition.Join_Condition import project.Data.Join_Kind.Join_Kind import project.Data.Match_Columns.Match_Columns import project.Data.Position.Position +import project.Data.Row.Row import project.Data.Storage.Storage import project.Data.Value_Type.Value_Type import project.Data.Sort_Column_Selector.Sort_Column_Selector @@ -38,7 +39,7 @@ import project.Delimited.Delimited_Format.Delimited_Format from project.Data.Column_Type_Selection import Column_Type_Selection, Auto from project.Internal.Rows_View import Rows_View -from project.Errors import Missing_Input_Columns, Column_Indexes_Out_Of_Range, Duplicate_Type_Selector, No_Index_Set_Error, No_Such_Column, No_Input_Columns_Selected, No_Output_Columns, Invalid_Value_Type +from project.Errors import Column_Count_Mismatch, Missing_Input_Columns, Column_Indexes_Out_Of_Range, Duplicate_Type_Selector, No_Index_Set_Error, No_Such_Column, No_Input_Columns_Selected, No_Output_Columns, Invalid_Value_Type from project.Data.Column import get_item_string from project.Internal.Filter_Condition_Helpers import make_filter_column @@ -1373,7 +1374,7 @@ type Table from Standard.Table import Excel example_to_xlsx = Examples.inventory_table.write (enso_project.data / "example_xlsx_output.xlsx") Excel - write : File|Text -> File_Format -> Existing_File_Behavior -> Match_Columns -> Problem_Behavior -> Nothing ! Column_Mismatch | Illegal_Argument | File_Error + write : File|Text -> File_Format -> Existing_File_Behavior -> Match_Columns -> Problem_Behavior -> Nothing ! Column_Count_Mismatch | Illegal_Argument | File_Error write self path format=Auto_Detect on_existing_file=Existing_File_Behavior.Backup match_columns=Match_Columns.By_Name on_problems=Report_Warning = file = File.new path case format of diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Reader.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Reader.enso index cc021a096c..0e3c04ab8b 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Reader.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Reader.enso @@ -1,5 +1,6 @@ from Standard.Base import all import Standard.Base.Error.File_Error.File_Error +import Standard.Base.System.File.Input_Stream import project.Data.Table.Table import project.Excel.Excel_Range.Excel_Range diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Writer.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Writer.enso index b466fd4db4..af62afc9c5 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Writer.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Writer.enso @@ -2,7 +2,7 @@ from Standard.Base import all import Standard.Base.Error.Illegal_Argument.Illegal_Argument import Standard.Base.Error.Illegal_State.Illegal_State -import project.Data.Table +import project.Data.Table.Table import project.Data.Match_Columns.Match_Columns import project.Excel.Excel_Range.Excel_Range import project.Excel.Excel_Section.Excel_Section diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Table_Helpers.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Table_Helpers.enso index 98b1c9d2d9..2d06350dff 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Table_Helpers.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Table_Helpers.enso @@ -4,6 +4,7 @@ import Standard.Base.Data.Ordering.Vector_Lexicographic_Order import Standard.Base.Error.Illegal_Argument.Illegal_Argument import Standard.Base.Error.Illegal_State.Illegal_State +import project.Data.Column.Column import project.Data.Column_Name_Mapping.Column_Name_Mapping import project.Data.Column_Selector.Column_Selector import project.Data.Position.Position @@ -192,7 +193,7 @@ type Table_Column_Helper A helper function which selects a single column from the table. It is aligned with the `select_columns_helper`, apart from Blank_Columns selector which is only handled by the other method but not this one. - resolve_column_helper : (Integer | Text | Column) -> Problem_Builder -> a | Nothing + resolve_column_helper : (Integer | Text | Column) -> Problem_Builder -> Any | Nothing resolve_column_helper self selector problem_builder = case selector of _ : Text -> matched_columns = self.internal_columns.filter column->(column.name==selector) diff --git a/distribution/lib/Standard/Test/0.0.0-dev/src/Suite_Config.enso b/distribution/lib/Standard/Test/0.0.0-dev/src/Suite_Config.enso index 33c074936f..637a3ed945 100644 --- a/distribution/lib/Standard/Test/0.0.0-dev/src/Suite_Config.enso +++ b/distribution/lib/Standard/Test/0.0.0-dev/src/Suite_Config.enso @@ -1,5 +1,6 @@ from Standard.Base import all import Standard.Base.Runtime.Source_Location.Source_Location +import Standard.Base.Runtime.Stack_Trace_Element polyglot java import java.lang.NullPointerException diff --git a/distribution/lib/Standard/Visualization/0.0.0-dev/src/Scatter_Plot.enso b/distribution/lib/Standard/Visualization/0.0.0-dev/src/Scatter_Plot.enso index 95f1684f7d..c7d710c931 100644 --- a/distribution/lib/Standard/Visualization/0.0.0-dev/src/Scatter_Plot.enso +++ b/distribution/lib/Standard/Visualization/0.0.0-dev/src/Scatter_Plot.enso @@ -174,14 +174,14 @@ limit_data limit data = case limit of extreme + data.take (Index_Sub_Range.Sample (limit - extreme.length)) ## PRIVATE -json_from_table : Table -> [Int]|Nothing -> Int|Nothing -> Text +json_from_table : Table -> [Integer]|Nothing -> Integer|Nothing -> Text json_from_table table bounds limit = data = table.point_data |> bound_data bounds |> limit_data limit axes = table.axes JS_Object.from_pairs [[data_field, data], [axis_field, axes]] . to_json ## PRIVATE -json_from_vector : Vector Any -> [Int]|Nothing -> Int|Nothing -> Text +json_from_vector : Vector Any -> [Integer]|Nothing -> Integer|Nothing -> Text json_from_vector vec bounds limit = data = vec.point_data |> bound_data bounds |> limit_data limit JS_Object.from_pairs [[data_field, data], [axis_field, Nothing]] . to_json diff --git a/distribution/lib/Standard/Visualization/0.0.0-dev/src/Table/Visualization.enso b/distribution/lib/Standard/Visualization/0.0.0-dev/src/Table/Visualization.enso index 5634808b3d..2636417cb9 100644 --- a/distribution/lib/Standard/Visualization/0.0.0-dev/src/Table/Visualization.enso +++ b/distribution/lib/Standard/Visualization/0.0.0-dev/src/Table/Visualization.enso @@ -69,7 +69,7 @@ prepare_visualization x max_rows=1000 = Helpers.recover_errors <| case x of `dataframe`. - all_rows_count: the number of all rows in the underlying data, useful if only a fragment is displayed. -make_json : (Dataframe_Table | Database_Table) -> Vector Column -> Integer -> Text +make_json : (Dataframe_Table | Database_Table) -> Vector Dataframe_Column -> Integer -> Text make_json dataframe indices all_rows_count = columns = dataframe.columns header = ["header", columns.map .name] diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/GatherDiagnostics.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/GatherDiagnostics.scala index 85351d7dd7..3e6d7150d6 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/GatherDiagnostics.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/analyse/GatherDiagnostics.scala @@ -5,6 +5,7 @@ import org.enso.compiler.context.{InlineContext, ModuleContext} import org.enso.compiler.core.IR import org.enso.compiler.core.ir.MetadataStorage._ import org.enso.compiler.pass.IRPass +import org.enso.compiler.pass.resolve.TypeSignatures import scala.annotation.unused @@ -19,7 +20,7 @@ case object GatherDiagnostics extends IRPass { override type Metadata = DiagnosticsMeta override type Config = IRPass.Configuration.Default - override val precursorPasses: Seq[IRPass] = List() + override val precursorPasses: Seq[IRPass] = List(TypeSignatures) override val invalidatedPasses: Seq[IRPass] = List() /** Executes the pass on the provided `ir`, and attaches all the encountered @@ -63,8 +64,17 @@ case object GatherDiagnostics extends IRPass { */ private def gatherMetadata(ir: IR): DiagnosticsMeta = { val diagnostics = ir.preorder.collect { - case err: IR.Diagnostic => List(err) - case x => x.diagnostics.toList + case err: IR.Diagnostic => + List(err) + case x: IR.Module.Scope.Definition.Method => + val typeSignatureDiagnostics = + x.getMetadata(TypeSignatures) + .map(_.signature.preorder.collect { case err: IR.Diagnostic => + err + }) + .getOrElse(Nil) + typeSignatureDiagnostics ++ x.diagnostics.toList + case x => x.diagnostics.toList }.flatten DiagnosticsMeta( diagnostics.distinctBy(d => new DiagnosticKeys(d)) diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/TypeNames.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/TypeNames.scala index e709fb0f02..5cee00c819 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/TypeNames.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/TypeNames.scala @@ -4,7 +4,7 @@ import org.enso.compiler.context.{InlineContext, ModuleContext} import org.enso.compiler.core.IR import org.enso.compiler.core.ir.MetadataStorage.ToPair import org.enso.compiler.data.BindingsMap -import org.enso.compiler.data.BindingsMap.Resolution +import org.enso.compiler.data.BindingsMap.{Resolution, ResolvedModule} import org.enso.compiler.pass.IRPass import org.enso.compiler.pass.analyse.BindingAnalysis @@ -74,11 +74,25 @@ case object TypeNames extends IRPass { bindingsMap: BindingsMap, expression: IR.Expression ): IR.Expression = - expression.transformExpressions { case n: IR.Name.Literal => - bindingsMap - .resolveName(n.name) - .map(res => n.updateMetadata(this -->> Resolution(res))) - .getOrElse(n) + expression.transformExpressions { + case expr if SuspendedArguments.representsSuspended(expr) => expr + case n: IR.Name.Literal => + bindingsMap + .resolveName(n.name) + .map(res => n.updateMetadata(this -->> Resolution(res))) + .fold( + error => + IR.Error.Resolution(n, IR.Error.Resolution.ResolverError(error)), + n => + n.getMetadata(this).get.target match { + case _: ResolvedModule => + IR.Error.Resolution( + n, + IR.Error.Resolution.UnexpectedModule("type signature") + ) + case _ => n + } + ) } /** Executes the pass on the provided `ir`, and returns a possibly transformed diff --git a/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala b/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala index 6cbac253eb..a7b7e71856 100644 --- a/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala +++ b/engine/runtime/src/main/scala/org/enso/compiler/pass/resolve/TypeSignatures.scala @@ -83,11 +83,7 @@ case object TypeSignatures extends IRPass { val newBindings: List[IR.Module.Scope.Definition] = mod.bindings.flatMap { case sig: IR.Type.Ascription => - val res = lastSignature match { - case Some(oldSig) => Some(IR.Error.Unexpected.TypeSignature(oldSig)) - case None => None - } - + val res = lastSignature.map(IR.Error.Unexpected.TypeSignature(_)) lastSignature = Some(sig) res case meth: IR.Module.Scope.Definition.Method => diff --git a/engine/runtime/src/test/scala/org/enso/compiler/test/pass/resolve/TypeNamesTest.scala b/engine/runtime/src/test/scala/org/enso/compiler/test/pass/resolve/TypeNamesTest.scala new file mode 100644 index 0000000000..a7147210cb --- /dev/null +++ b/engine/runtime/src/test/scala/org/enso/compiler/test/pass/resolve/TypeNamesTest.scala @@ -0,0 +1,174 @@ +package org.enso.compiler.test.pass.resolve + +import org.enso.compiler.Passes +import org.enso.compiler.context.{FreshNameSupply, InlineContext, ModuleContext} +import org.enso.compiler.core.IR +import org.enso.compiler.data.BindingsMap.ResolutionNotFound +import org.enso.compiler.pass.{PassConfiguration, PassGroup, PassManager} +import org.enso.compiler.pass.resolve.{TypeNames, TypeSignatures} +import org.enso.compiler.test.CompilerTest + +class TypeNamesTest extends CompilerTest { + + // === Test Setup =========================================================== + + val passes = new Passes(defaultConfig) + + val precursorPasses: PassGroup = passes.getPrecursors(TypeNames).get + + val passConfiguration: PassConfiguration = PassConfiguration() + + implicit val passManager: PassManager = + new PassManager(List(precursorPasses), passConfiguration) + + /** Adds an extension method to a module for performing type signature + * resolution. + * + * @param ir the IR to add the extension method to + */ + implicit class ResolveModule(ir: IR.Module) { + + /** Resolves type signatures in [[ir]]. + * + * @param moduleContext the context in which resolution is taking place + * @return [[ir]], with all type signatures resolved + */ + def resolve(implicit moduleContext: ModuleContext): IR.Module = { + TypeNames.runModule(ir, moduleContext) + } + } + + /** Adds an extension method to an expression for performing type signature + * resolution. + * + * @param ir the expression to add the extension method to + */ + implicit class ResolveExpression(ir: IR.Expression) { + + /** Resolves type signatures in [[ir]]. + * + * @param inlineContext the context in which resolution is taking place + * @return [[ir]], with all type signatures resolved + */ + def resolve(implicit inlineContext: InlineContext): IR.Expression = { + TypeNames.runExpression(ir, inlineContext) + } + } + + /** Creates a defaulted module context. + * + * @return a defaulted module context + */ + def mkModuleContext: ModuleContext = { + buildModuleContext(freshNameSupply = Some(new FreshNameSupply)) + } + + /** Creates a defaulted inline context. + * + * @return a defaulted inline context + */ + def mkInlineContext: InlineContext = { + buildInlineContext(freshNameSupply = Some(new FreshNameSupply)) + } + + // === The Tests ============================================================ + + "Resolution of type names in modules" should { + implicit val ctx: ModuleContext = mkModuleContext + + "should correctly resolve local type names" in { + val ir = + """ + |type A + |type B + |type C + | + |foo : A -> B -> C + |foo a b = a + b + |""".stripMargin.preprocessModule.resolve + + ir.bindings.length shouldEqual 4 + val meta = ir.bindings.last.getMetadata(TypeSignatures) + meta shouldBe defined + val diagnostics = meta.get.signature.preorder + .collect({ case err: IR.Diagnostic => + err + }) + + diagnostics shouldBe Nil + } + + "should report failures when type name is unknown" in { + val ir = + """ + |type A + |type B + | + |foo : A -> B -> C + |foo a b = a + b + |""".stripMargin.preprocessModule.resolve + + ir.bindings.length shouldEqual 3 + val meta = ir.bindings.last.getMetadata(TypeSignatures) + meta shouldBe defined + val diagnostics = meta.get.signature.preorder + .collect({ case err: IR.Diagnostic => + err + }) + + diagnostics.length shouldEqual 1 + val resolutionFailure = diagnostics.head.asInstanceOf[IR.Error.Resolution] + resolutionFailure.name shouldBe "C" + resolutionFailure.reason shouldBe IR.Error.Resolution.ResolverError( + ResolutionNotFound + ) + } + + "should report every failed name resolution" in { + val ir = + """ + |foo : Integer -> Integer -> Integer + |foo a b = a + b + |""".stripMargin.preprocessModule.resolve + + ir.bindings.length shouldEqual 1 + val meta = ir.bindings.last.getMetadata(TypeSignatures) + meta shouldBe defined + val diagnostics = meta.get.signature.preorder + .collect({ case err: IR.Diagnostic => + err + }) + + diagnostics.length shouldEqual 3 + diagnostics.foreach { + case d: IR.Error.Resolution => + d.name shouldBe "Integer" + d.reason shouldBe IR.Error.Resolution.ResolverError( + ResolutionNotFound + ) + case _ => + fail() + } + } + + "should treat Suspended type specially" in { + val ir = + """ + |type A + | + |foo : A -> Suspended -> A + |foo a b = a + b + |""".stripMargin.preprocessModule.resolve + + ir.bindings.length shouldEqual 2 + val meta = ir.bindings.last.getMetadata(TypeSignatures) + meta shouldBe defined + val diagnostics = meta.get.signature.preorder + .collect({ case err: IR.Diagnostic => + err + }) + + diagnostics.length shouldEqual 0 + } + } +} diff --git a/engine/runtime/src/test/scala/org/enso/compiler/test/pass/resolve/TypeSignaturesTest.scala b/engine/runtime/src/test/scala/org/enso/compiler/test/pass/resolve/TypeSignaturesTest.scala index 72872aea80..c0db0b1611 100644 --- a/engine/runtime/src/test/scala/org/enso/compiler/test/pass/resolve/TypeSignaturesTest.scala +++ b/engine/runtime/src/test/scala/org/enso/compiler/test/pass/resolve/TypeSignaturesTest.scala @@ -155,7 +155,7 @@ class TypeSignaturesTest extends CompilerTest { | MyAtom | | ## is atom - | is_atom : this -> Boolean + | is_atom : Boolean | is_atom = true | | error_signature : Int diff --git a/engine/runtime/src/test/scala/org/enso/compiler/test/semantic/TypeSignaturesTest.scala b/engine/runtime/src/test/scala/org/enso/compiler/test/semantic/TypeSignaturesTest.scala index ab88b81775..9b3f1ff8c6 100644 --- a/engine/runtime/src/test/scala/org/enso/compiler/test/semantic/TypeSignaturesTest.scala +++ b/engine/runtime/src/test/scala/org/enso/compiler/test/semantic/TypeSignaturesTest.scala @@ -174,6 +174,9 @@ class TypeSignaturesTest "be parsed in a simple scenario" in { val code = """ + |type Text + |type Number + | |foo : Text -> Number |foo a = 42""".stripMargin val module = code.preprocessModule @@ -244,6 +247,11 @@ class TypeSignaturesTest "resolve execution contexts" in { val code = """ + |type A + |type B + |type C + |type Input + | |foo : A -> B -> C in Input |foo a b = c |""".stripMargin diff --git a/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/IOContextTest.scala b/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/IOContextTest.scala index 8184781ea9..0193eb2529 100644 --- a/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/IOContextTest.scala +++ b/engine/runtime/src/test/scala/org/enso/interpreter/test/semantic/IOContextTest.scala @@ -18,6 +18,7 @@ class DevelopmentContextTest extends InterpreterTest { "error on Input actions" in { val code = """from Standard.Base import all + |from Standard.Base.Runtime.IO_Permissions import Input | |input_action : Integer -> Integer in Input |input_action i = i @@ -30,6 +31,7 @@ class DevelopmentContextTest extends InterpreterTest { "error on Output actions" in { val code = """from Standard.Base import all + |from Standard.Base.Runtime.IO_Permissions import Output | |output_action : Integer -> Nothing in Output |output_action i = i @@ -42,6 +44,7 @@ class DevelopmentContextTest extends InterpreterTest { "allow locally running IO" in { val code = """from Standard.Base import all + |from Standard.Base.Runtime.IO_Permissions import Input, Output | |output_action : Integer -> Integer in Output |output_action i = i + 1 @@ -69,6 +72,7 @@ class ProductionContextTest extends InterpreterTest { "allow all IO" in { val code = """from Standard.Base import all + |from Standard.Base.Runtime.IO_Permissions import Input, Output | |output_action : Integer -> Integer in Output |output_action i = i + 1 diff --git a/test/Tests/src/Semantic/Equals_Spec.enso b/test/Tests/src/Semantic/Equals_Spec.enso index 035c81c154..3c59da90a4 100644 --- a/test/Tests/src/Semantic/Equals_Spec.enso +++ b/test/Tests/src/Semantic/Equals_Spec.enso @@ -4,6 +4,7 @@ from Standard.Test import Test, Test_Suite import Standard.Test.Extensions polyglot java import java.util.HashMap +polyglot java import java.util.Random as Java_Random type CustomEqType C1 f1 diff --git a/test/Tests/src/Semantic/Runtime_Spec.enso b/test/Tests/src/Semantic/Runtime_Spec.enso index 113a5a0a6c..b50a5692a5 100644 --- a/test/Tests/src/Semantic/Runtime_Spec.enso +++ b/test/Tests/src/Semantic/Runtime_Spec.enso @@ -1,12 +1,15 @@ import Standard.Base.Runtime +import Standard.Base.Data.Numbers.Integer + +from Standard.Base.Runtime.IO_Permissions import Input, Output from Standard.Test import Test import Standard.Test.Extensions -in_fn : Int -> Int in Input +in_fn : Integer -> Integer in Input in_fn a = a * 2 -out_fn : Int -> Int in Output +out_fn : Integer -> Integer in Output out_fn a = a + 1 spec = diff --git a/test/micro-distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso b/test/micro-distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso index 51ee48659f..720c416ee0 100644 --- a/test/micro-distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso +++ b/test/micro-distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso @@ -1,3 +1,7 @@ +type IO_Permissions + Input + Output + primitive_get_stack_trace = @Builtin_Method "Runtime.primitive_get_stack_trace" allow_input_in env = @Builtin_Method "Runtime.allow_input_in" allow_output_in env = @Builtin_Method "Runtime.allow_output_in"