mirror of
https://github.com/AdaCore/langkit.git
synced 2026-02-12 12:28:12 -08:00
Implement a new typer for Lkt using the Logic DSL
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
with Ada.Command_Line; use Ada.Command_Line;
|
||||
with Ada.Command_Line; use Ada.Command_Line;
|
||||
with Ada.Containers.Hashed_Maps;
|
||||
with Ada.Directories; use Ada.Directories;
|
||||
with Ada.Directories; use Ada.Directories;
|
||||
with Ada.Exceptions;
|
||||
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
|
||||
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
|
||||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
|
||||
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
|
||||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
with Ada.Wide_Wide_Text_IO;
|
||||
|
||||
with GNAT.Traceback.Symbolic;
|
||||
with GNATCOLL.Opt_Parse; use GNATCOLL.Opt_Parse;
|
||||
with GNATCOLL.Traces;
|
||||
with GNATCOLL.Opt_Parse; use GNATCOLL.Opt_Parse;
|
||||
|
||||
with Liblktlang_Support.Diagnostics; use Liblktlang_Support.Diagnostics;
|
||||
with Liblktlang.Analysis; use Liblktlang.Analysis;
|
||||
with Liblktlang.Common;
|
||||
with Liblktlang.Semantic_Diagnostics; use Liblktlang.Semantic_Diagnostics;
|
||||
with Liblktlang_Support.Diagnostics; use Liblktlang_Support.Diagnostics;
|
||||
with Liblktlang_Support.Diagnostics.Output;
|
||||
use Liblktlang_Support.Diagnostics.Output;
|
||||
with Liblktlang_Support.Slocs; use Liblktlang_Support.Slocs;
|
||||
with Liblktlang_Support.Text; use Liblktlang_Support.Text;
|
||||
|
||||
with Liblktlang.Analysis; use Liblktlang.Analysis;
|
||||
with Liblktlang.Common;
|
||||
with Liblktlang_Support.Slocs; use Liblktlang_Support.Slocs;
|
||||
with Liblktlang_Support.Text; use Liblktlang_Support.Text;
|
||||
|
||||
procedure Lkt_Toolbox is
|
||||
|
||||
@@ -46,6 +46,20 @@ procedure Lkt_Toolbox is
|
||||
Help => "Flag decls that generate errors that are not annotated"
|
||||
& " with the @invalid annotation. Also flag decls"
|
||||
& " annotated with @invalid that don't trigger any errors");
|
||||
|
||||
package Debug_Solver is new Parse_Flag
|
||||
(Parser => Parser,
|
||||
Short => "-D",
|
||||
Long => "--debug",
|
||||
Help => "Enable Solver debug traces");
|
||||
|
||||
package Solve_Line is new Parse_Option
|
||||
(Parser => Parser,
|
||||
Short => "-L",
|
||||
Long => "--solve-line",
|
||||
Arg_Type => Natural,
|
||||
Help => "Only do name resolution at line N",
|
||||
Default_Val => 0);
|
||||
end Arg;
|
||||
|
||||
use Liblktlang;
|
||||
@@ -56,18 +70,21 @@ procedure Lkt_Toolbox is
|
||||
Hash => Analysis.Hash,
|
||||
Equivalent_Keys => "=");
|
||||
|
||||
procedure Print_Semantic_Result
|
||||
(S : Analysis.Semantic_Result; Unit : Analysis.Analysis_Unit);
|
||||
-- Print a semantic result
|
||||
|
||||
function Format_Node (Decl_Node : Decl'Class) return String;
|
||||
-- Format node for semantic result printing
|
||||
|
||||
procedure Print_Lkt_Toolbox_Diagnostic
|
||||
(Node : Lkt_Node'Class; Message : Wide_Wide_String);
|
||||
(Node : Lkt_Node'Class; Message : Text_Type);
|
||||
-- Internal wrapper to ``Print_Diagnostic`` used by lkt_toolbox to print
|
||||
-- additional diagnostics.
|
||||
|
||||
procedure Print_Nameres_Results
|
||||
(Node : Lkt_Node'Class; Perform_Analysis : Boolean := False);
|
||||
-- Print name and type resolution information about a node if
|
||||
-- ``Perform_Analysis`` is ``True`` and recurse on its children for testing
|
||||
-- and debugging purposes.
|
||||
--
|
||||
-- The value of ``Perform_Analysis`` will be given to recursive calls, but
|
||||
-- may change to ``True`` when the node's source location line is equal to
|
||||
-- ``Solve_Line``.
|
||||
|
||||
function Populate_Invalid_Decl_Map
|
||||
(Node : Analysis.Lkt_Node'Class) return Common.Visit_Status;
|
||||
-- Populate ``Invalid_Decl_Map`` and reject declarations with ``@invalid``
|
||||
@@ -81,23 +98,12 @@ procedure Lkt_Toolbox is
|
||||
-- is used to check that at least one diagnostic has been emitted for each
|
||||
-- declaration annotated with ``@invalid``.
|
||||
|
||||
-----------------
|
||||
-- Format_Node --
|
||||
-----------------
|
||||
|
||||
function Format_Node (Decl_Node : Decl'Class) return String is
|
||||
begin
|
||||
-- Remove rebindings information as there is no easy way to filter
|
||||
-- out/format rebindings information involving prelude declarations.
|
||||
return Decl_Node.P_As_Bare_Decl.Image;
|
||||
end Format_Node;
|
||||
|
||||
----------------------------------
|
||||
-- Print_Lkt_Toolbox_Diagnostic --
|
||||
----------------------------------
|
||||
|
||||
procedure Print_Lkt_Toolbox_Diagnostic
|
||||
(Node : Lkt_Node'Class; Message : Wide_Wide_String)
|
||||
(Node : Lkt_Node'Class; Message : Text_Type)
|
||||
is
|
||||
Sloc_Range : constant Source_Location_Range := Node.Sloc_Range;
|
||||
Unit : constant Analysis.Analysis_Unit := Node.Unit;
|
||||
@@ -107,55 +113,162 @@ procedure Lkt_Toolbox is
|
||||
end Print_Lkt_Toolbox_Diagnostic;
|
||||
|
||||
---------------------------
|
||||
-- Print_Semantic_Result --
|
||||
-- Print_Nameres_Results --
|
||||
---------------------------
|
||||
|
||||
procedure Print_Semantic_Result
|
||||
(S : Analysis.Semantic_Result; Unit : Analysis.Analysis_Unit)
|
||||
Indent : Natural := 0;
|
||||
|
||||
procedure Print_Nameres_Results
|
||||
(Node : Lkt_Node'Class; Perform_Analysis : Boolean := False)
|
||||
is
|
||||
Node : constant Lkt_Node'Class := Analysis.Node (S);
|
||||
procedure Put_Line_Indent (Item : Text_Type);
|
||||
-- Print ``Item`` on the standard output with indentation (using
|
||||
-- ``Indent`` to determine how much to indent).
|
||||
|
||||
function Get_Custom_Image
|
||||
(Node : Lkt_Node'Class) return Text_Type;
|
||||
-- Wrapper around the various ``P_Custom_Image`` node properties that
|
||||
-- handles null nodes in addition.
|
||||
|
||||
procedure Print_Expr_Nameres (Node : Expr'Class);
|
||||
-- Print the type and name resolution of an Expr
|
||||
|
||||
procedure Print_Ref_Id_Nameres (Node : Ref_Id'Class);
|
||||
-- Print the type and name resolution of a Ref_Id
|
||||
|
||||
procedure Print_Base_Val_Decl_Nameres (Node : Base_Val_Decl'Class);
|
||||
-- Print the type and name resolution of an Base_Val_Decl
|
||||
|
||||
---------------------
|
||||
-- Put_Line_Indent --
|
||||
---------------------
|
||||
|
||||
procedure Put_Line_Indent (Item : Text_Type)
|
||||
is
|
||||
use Ada.Wide_Wide_Text_IO;
|
||||
begin
|
||||
Put (Indent * " ");
|
||||
Put_Line (Item);
|
||||
end Put_Line_Indent;
|
||||
|
||||
----------------------
|
||||
-- Get_Custom_Image --
|
||||
----------------------
|
||||
|
||||
function Get_Custom_Image (Node : Lkt_Node'Class) return Text_Type
|
||||
is
|
||||
use type Common.Lkt_Node_Kind_Type;
|
||||
begin
|
||||
if Node.Is_Null then
|
||||
return "None";
|
||||
elsif Node.Kind in Common.Lkt_Decl then
|
||||
return Node.As_Decl.P_Custom_Image;
|
||||
elsif Node.Kind = Common.Lkt_Ref_Id then
|
||||
return Node.As_Ref_Id.P_Custom_Image;
|
||||
else
|
||||
return To_Text (Node.Image);
|
||||
end if;
|
||||
end Get_Custom_Image;
|
||||
|
||||
------------------------
|
||||
-- Print_Expr_Nameres --
|
||||
------------------------
|
||||
|
||||
procedure Print_Expr_Nameres (Node : Expr'Class) is
|
||||
begin
|
||||
Put_Line_Indent ("Expr " & Get_Custom_Image (Node));
|
||||
Put_Line_Indent
|
||||
(" has_type " & Get_Custom_Image (Node.P_Get_Type));
|
||||
New_Line;
|
||||
end Print_Expr_Nameres;
|
||||
|
||||
--------------------------
|
||||
-- Print_Ref_Id_Nameres --
|
||||
--------------------------
|
||||
|
||||
procedure Print_Ref_Id_Nameres (Node : Ref_Id'Class) is
|
||||
begin
|
||||
Put_Line_Indent ("Id " & Get_Custom_Image (Node));
|
||||
Put_Line_Indent
|
||||
(" has_type " & Get_Custom_Image (Node.P_Get_Type));
|
||||
Put_Line_Indent
|
||||
(" references " & Get_Custom_Image (Node.P_Referenced_Decl));
|
||||
New_Line;
|
||||
end Print_Ref_Id_Nameres;
|
||||
|
||||
---------------------------------
|
||||
-- Print_Base_Val_Decl_Nameres --
|
||||
---------------------------------
|
||||
|
||||
procedure Print_Base_Val_Decl_Nameres (Node : Base_Val_Decl'Class) is
|
||||
begin
|
||||
Put_Line_Indent ("Decl " & Get_Custom_Image (Node));
|
||||
Put_Line_Indent
|
||||
(" has_type " & Get_Custom_Image (Node.P_Get_Type));
|
||||
New_Line;
|
||||
end Print_Base_Val_Decl_Nameres;
|
||||
|
||||
use type Common.Lkt_Node_Kind_Type;
|
||||
|
||||
Indented : Boolean := False;
|
||||
|
||||
Node_Line : constant Line_Number := Sloc_Range (Node).Start_Line;
|
||||
Allowed_Line : constant Line_Number := Line_Number (Arg.Solve_Line.Get);
|
||||
Can_Nameres : constant Boolean :=
|
||||
Perform_Analysis or else Node_Line = Allowed_Line;
|
||||
begin
|
||||
if Analysis.Error_Message (S) /= "" then
|
||||
declare
|
||||
Diag : constant Diagnostic :=
|
||||
(Node.Sloc_Range,
|
||||
To_Unbounded_Text (Analysis.Error_Message (S)));
|
||||
begin
|
||||
if Arg.Flag_Invalid.Get then
|
||||
-- Emit an error if the declaration including ``Node`` has no
|
||||
-- ``@invalid`` annotation. Update ``Invalid_Decl_Map``
|
||||
-- otherwise.
|
||||
if Node.P_Topmost_Invalid_Decl.Is_Null then
|
||||
Set_Exit_Status (1);
|
||||
|
||||
Print_Lkt_Toolbox_Diagnostic
|
||||
(Node,
|
||||
"unexpected diagnostic, is @invalid annotation missing?");
|
||||
else
|
||||
Invalid_Decl_Map (Node.P_Topmost_Invalid_Decl) := True;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
Print_Diagnostic
|
||||
(Diag, Unit, Simple_Name (Node.Unit.Get_Filename));
|
||||
end;
|
||||
elsif
|
||||
not Arg.Check_Only.Get
|
||||
and then not Analysis.Result_Type (S).Is_Null
|
||||
then
|
||||
Put_Line ("Expr " & Node.Image);
|
||||
Put_Line (" has type " & Analysis.Result_Type (S).Image);
|
||||
New_Line;
|
||||
elsif
|
||||
not Arg.Check_Only.Get
|
||||
and then not Analysis.Result_Decl (S).Is_Null
|
||||
then
|
||||
Put_Line ("Id " & Node.Image);
|
||||
Put_Line
|
||||
(" references " & Format_Node (Analysis.Result_Decl (S)));
|
||||
New_Line;
|
||||
-- The Lkt specification does not handle name and type resolution in
|
||||
-- lexer and grammar declarations: ignore them.
|
||||
if Node.Kind in Common.Lkt_Lexer_Decl | Common.Lkt_Grammar_Decl then
|
||||
return;
|
||||
end if;
|
||||
end Print_Semantic_Result;
|
||||
|
||||
-- If the analysis was not successful, print the emitted diagnostics.
|
||||
-- In any case, print the resulting name and type resolution
|
||||
-- information.
|
||||
if Can_Nameres then
|
||||
if Node.P_Xref_Entry_Point then
|
||||
declare
|
||||
Results : constant Solver_Result :=
|
||||
Node.P_Solve_Enclosing_Context;
|
||||
begin
|
||||
if not Analysis.Success (Results) then
|
||||
Put_Line (Node.Image & " failed nameres:");
|
||||
for Diagnostic of Analysis.Diagnostics (Results) loop
|
||||
Print_Solver_Diagnostic (Diagnostic);
|
||||
New_Line;
|
||||
end loop;
|
||||
end if;
|
||||
end;
|
||||
end if;
|
||||
if Node.Kind = Common.Lkt_Ref_Id then
|
||||
Print_Ref_Id_Nameres (Node.As_Ref_Id);
|
||||
Indented := True;
|
||||
Indent := Indent + 1;
|
||||
elsif Node.Kind = Common.Lkt_Def_Id then
|
||||
null;
|
||||
elsif Node.Kind in Common.Lkt_Base_Val_Decl then
|
||||
Print_Base_Val_Decl_Nameres (Node.As_Base_Val_Decl);
|
||||
Indented := True;
|
||||
Indent := Indent + 1;
|
||||
elsif Node.Kind in Common.Lkt_Expr then
|
||||
Print_Expr_Nameres (Node.As_Expr);
|
||||
Indented := True;
|
||||
Indent := Indent + 1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
for Child of Node.Children loop
|
||||
if not Child.Is_Null then
|
||||
Print_Nameres_Results (Child, Can_Nameres);
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
if Indented then
|
||||
Indent := Indent - 1;
|
||||
end if;
|
||||
|
||||
end Print_Nameres_Results;
|
||||
|
||||
-------------------------------
|
||||
-- Populate_Invalid_Decl_Map --
|
||||
@@ -190,9 +303,8 @@ procedure Lkt_Toolbox is
|
||||
|
||||
Ctx : constant Analysis.Analysis_Context := Analysis.Create_Context;
|
||||
begin
|
||||
GNATCOLL.Traces.Parse_Config_File;
|
||||
|
||||
if Arg.Parser.Parse then
|
||||
Set_Solver_Debug_Mode (Arg.Debug_Solver.Get);
|
||||
for File_Name of Arg.Files.Get loop
|
||||
declare
|
||||
File_Name_Str : constant String := To_String (File_Name);
|
||||
@@ -216,14 +328,11 @@ begin
|
||||
Unit.Root.Traverse (Populate_Invalid_Decl_Map'Access);
|
||||
end if;
|
||||
|
||||
declare
|
||||
Diags : constant Analysis.Tree_Semantic_Result :=
|
||||
Unit.Root.As_Langkit_Root.P_Check_Semantic;
|
||||
begin
|
||||
for D of Analysis.Results (Diags) loop
|
||||
Print_Semantic_Result (D, Unit);
|
||||
end loop;
|
||||
end;
|
||||
if Arg.Check_Only.Get then
|
||||
Print_Solver_Diagnostics_In_Unit (Unit);
|
||||
else
|
||||
Print_Nameres_Results (Unit.Root, Arg.Solve_Line.Get = 0);
|
||||
end if;
|
||||
|
||||
if Arg.Flag_Invalid.Get then
|
||||
|
||||
|
||||
@@ -5,11 +5,13 @@ with Ada.Text_IO; use Ada.Text_IO;
|
||||
|
||||
with Interfaces; use Interfaces;
|
||||
|
||||
with Liblktlang_Support.Text; use Liblktlang_Support.Text;
|
||||
with GNATCOLL.Traces;
|
||||
|
||||
with Liblktlang.Analysis; use Liblktlang.Analysis;
|
||||
with Liblktlang.Prelude;
|
||||
with Liblktlang.Public_Converters; use Liblktlang.Public_Converters;
|
||||
with Liblktlang_Support.Adalog.Debug;
|
||||
with Liblktlang_Support.Text; use Liblktlang_Support.Text;
|
||||
|
||||
package body Liblktlang.Implementation.Extensions is
|
||||
|
||||
@@ -251,7 +253,7 @@ package body Liblktlang.Implementation.Extensions is
|
||||
----------------------------------
|
||||
|
||||
function Langkit_Root_P_Fetch_Prelude
|
||||
(Node : Bare_Langkit_Root) return Boolean
|
||||
(Node : Bare_Langkit_Root) return Internal_Unit
|
||||
is
|
||||
Ctx : constant Analysis_Context := Wrap_Context (Node.Unit.Context);
|
||||
Prelude : Analysis_Unit;
|
||||
@@ -261,8 +263,8 @@ package body Liblktlang.Implementation.Extensions is
|
||||
Prelude := Ctx.Get_From_Buffer
|
||||
("__prelude", "ascii", Liblktlang.Prelude.Content);
|
||||
|
||||
-- Check if we have syntactic or semantic errors in the prelude. If
|
||||
-- we do, raise an assertion error.
|
||||
-- Check if we have syntactic errors in the prelude. If we do, raise
|
||||
-- an assertion error.
|
||||
|
||||
if Prelude.Diagnostics'Length > 0 then
|
||||
for Diagnostic of Prelude.Diagnostics loop
|
||||
@@ -271,67 +273,94 @@ package body Liblktlang.Implementation.Extensions is
|
||||
raise Assertion_Error with "Errors in prelude";
|
||||
end if;
|
||||
|
||||
declare
|
||||
Sem_Results : constant Tree_Semantic_Result :=
|
||||
Prelude.Root.As_Langkit_Root.P_Check_Semantic;
|
||||
begin
|
||||
if Analysis.Has_Error (Sem_Results) then
|
||||
for R of Analysis.Results (Sem_Results) loop
|
||||
if Analysis.Error_Message (R) /= "" then
|
||||
Put_Line
|
||||
(Image (Analysis.Node (R).Full_Sloc_Image
|
||||
& Error_Message (R)));
|
||||
end if;
|
||||
end loop;
|
||||
raise Assertion_Error with "Errors in prelude";
|
||||
end if;
|
||||
end;
|
||||
|
||||
Populate_Lexical_Env (Prelude);
|
||||
return True;
|
||||
else
|
||||
return False;
|
||||
end if;
|
||||
return Unwrap_Unit (Prelude);
|
||||
end Langkit_Root_P_Fetch_Prelude;
|
||||
|
||||
------------------------
|
||||
-- Ref_Id_Short_Image --
|
||||
------------------------
|
||||
--------------------------------------
|
||||
-- Lkt_Node_P_Set_Solver_Debug_Mode --
|
||||
--------------------------------------
|
||||
|
||||
function Ref_Id_Short_Image (Node : Bare_Ref_Id) return Text_Type is
|
||||
function Lkt_Node_P_Set_Solver_Debug_Mode
|
||||
(Node : Bare_Lkt_Node;
|
||||
Enable : Boolean) return Boolean
|
||||
is
|
||||
pragma Unreferenced (Node);
|
||||
use Liblktlang_Support.Adalog;
|
||||
begin
|
||||
GNATCOLL.Traces.Parse_Config_File;
|
||||
Debug.Set_Debug_State
|
||||
(if Enable then Debug.Trace else Debug.None);
|
||||
Solver_Trace.Set_Active (Enable);
|
||||
Solv_Trace.Set_Active (Enable);
|
||||
Sol_Trace.Set_Active (Enable);
|
||||
return True;
|
||||
end Lkt_Node_P_Set_Solver_Debug_Mode;
|
||||
|
||||
-----------------------
|
||||
-- Id_P_Custom_Image --
|
||||
-----------------------
|
||||
|
||||
function Id_P_Custom_Image
|
||||
(Node : Bare_Id; E_Info : Entity_Info) return String_Type
|
||||
is
|
||||
pragma Unreferenced (E_Info);
|
||||
begin
|
||||
return
|
||||
"<" & To_Text (Kind_Name (Node))
|
||||
& " """ & Text (Node) & """ "
|
||||
& To_Text (Ada.Directories.Simple_Name (Get_Filename (Unit (Node))))
|
||||
& ":" & To_Text (Image (Sloc_Range (Node))) & ">";
|
||||
end Ref_Id_Short_Image;
|
||||
Create_String
|
||||
("<" & To_Text (Node.Kind_Name) & " """ & Node.Text & """ "
|
||||
& To_Text (Ada.Directories.Simple_Name (Node.Unit.Get_Filename))
|
||||
& ":" & To_Text (Node.Sloc_Range.Image) & ">");
|
||||
end Id_P_Custom_Image;
|
||||
|
||||
----------------------
|
||||
-- Decl_Short_Image --
|
||||
----------------------
|
||||
-------------------------
|
||||
-- Decl_P_Custom_Image --
|
||||
-------------------------
|
||||
|
||||
function Decl_Short_Image (Node : Bare_Decl) return Text_Type is
|
||||
Full_Name_Acc : String_Type := Dispatcher_Decl_P_Full_Name (Node);
|
||||
function Decl_P_Custom_Image
|
||||
(Node : Bare_Decl; E_Info : Entity_Info) return String_Type
|
||||
is
|
||||
Full_Name_Acc : String_Type :=
|
||||
Dispatcher_Decl_P_Full_Name (Node, E_Info);
|
||||
Full_Name : constant Text_Type := Full_Name_Acc.Content;
|
||||
File_Name : constant Text_Type :=
|
||||
To_Text (Ada.Directories.Simple_Name (Get_Filename (Unit (Node))));
|
||||
begin
|
||||
Dec_Ref (Full_Name_Acc);
|
||||
if File_Name = "__prelude" then
|
||||
return "<" & To_Text (Kind_Name (Node))
|
||||
& " prelude: """ & Full_Name & """>";
|
||||
return Create_String ("<" & To_Text (Kind_Name (Node))
|
||||
& " prelude: """ & Full_Name & """>");
|
||||
else
|
||||
return "<" & To_Text (Kind_Name (Node)) & " """ & Full_Name & """ "
|
||||
& File_Name
|
||||
|
||||
-- Don't show the sloc for function types, because it will be the
|
||||
-- root node's sloc, and thus will always change when we add stuff
|
||||
-- to the file, which is not helpful nor practical for tests.
|
||||
& (if Node.Kind = Lkt_Function_Type
|
||||
then ""
|
||||
else ":" & To_Text (Image (Sloc_Range (Node)))) & ">";
|
||||
return Create_String
|
||||
("<" & To_Text (Kind_Name (Node)) & " """ & Full_Name & """ "
|
||||
& File_Name
|
||||
-- Don't show the sloc for function types, because it will be
|
||||
-- the root node's sloc, and thus will always change when we add
|
||||
-- stuff to the file, which is not helpful nor practical for
|
||||
-- tests.
|
||||
& (if Node.Kind = Lkt_Function_Type
|
||||
then ""
|
||||
else ":" & To_Text (Image (Sloc_Range (Node)))) & ">");
|
||||
end if;
|
||||
end Decl_P_Custom_Image;
|
||||
|
||||
--------------------
|
||||
-- Id_Short_Image --
|
||||
--------------------
|
||||
|
||||
function Id_Short_Image (Node : Bare_Id) return Text_Type is
|
||||
begin
|
||||
return Id_P_Custom_Image (Node, No_Entity_Info).Content;
|
||||
end Id_Short_Image;
|
||||
|
||||
----------------------
|
||||
-- Decl_Short_Image --
|
||||
----------------------
|
||||
|
||||
function Decl_Short_Image (Node : Bare_Decl) return Text_Type is
|
||||
begin
|
||||
return Decl_P_Custom_Image (Node, No_Entity_Info).Content;
|
||||
end Decl_Short_Image;
|
||||
|
||||
-----------------------
|
||||
@@ -348,26 +377,6 @@ package body Liblktlang.Implementation.Extensions is
|
||||
return N_Text'Length > 0 and then N_Text (N_Text'First) in 'A' .. 'Z';
|
||||
end Id_P_Is_Type_Name;
|
||||
|
||||
---------------------------------------
|
||||
-- Lkt_Node_P_Env_From_Vals_Internal --
|
||||
---------------------------------------
|
||||
|
||||
function Lkt_Node_P_Env_From_Vals_Internal
|
||||
(Node : Bare_Lkt_Node;
|
||||
Vals : Internal_Env_Kv_Array_Access) return Lexical_Env
|
||||
is
|
||||
Ret : constant Lexical_Env :=
|
||||
Create_Static_Lexical_Env
|
||||
(Null_Lexical_Env, Node, Node.Unit.Context.Symbols);
|
||||
begin
|
||||
|
||||
for El of Vals.Items loop
|
||||
AST_Envs.Add (Ret, Thin (El.Key), El.Value);
|
||||
end loop;
|
||||
|
||||
return Ret;
|
||||
end Lkt_Node_P_Env_From_Vals_Internal;
|
||||
|
||||
-----------------------------------------------
|
||||
-- Lkt_Node_P_Internal_Fetch_Referenced_Unit --
|
||||
-----------------------------------------------
|
||||
|
||||
@@ -1,23 +1,31 @@
|
||||
package Liblktlang.Implementation.Extensions is
|
||||
|
||||
function Langkit_Root_P_Fetch_Prelude
|
||||
(Node : Bare_Langkit_Root) return Boolean;
|
||||
(Node : Bare_Langkit_Root) return Internal_Unit;
|
||||
|
||||
function Lkt_Node_P_Set_Solver_Debug_Mode
|
||||
(Node : Bare_Lkt_Node;
|
||||
Enable : Boolean) return Boolean;
|
||||
|
||||
function Id_P_Custom_Image
|
||||
(Node : Bare_Id; E_Info : Entity_Info) return String_Type;
|
||||
-- Custom version of Image for Ids to keep Entity information
|
||||
|
||||
function Decl_P_Custom_Image
|
||||
(Node : Bare_Decl; E_Info : Entity_Info) return String_Type;
|
||||
-- Custom version of Image for Decls to keep Entity information
|
||||
|
||||
function Decl_Short_Image (Node : Bare_Decl) return Text_Type;
|
||||
-- Custom version of Short_Image for declarations. Include
|
||||
-- the names of the entities it declares.
|
||||
|
||||
function Ref_Id_Short_Image (Node : Bare_Ref_Id) return Text_Type;
|
||||
function Id_Short_Image (Node : Bare_Id) return Text_Type;
|
||||
-- Custom version of Short_Image for referencing identifiers. Include
|
||||
-- the identifier.
|
||||
|
||||
function Id_P_Is_Type_Name (Node : Bare_Id) return Boolean;
|
||||
-- Return whether this identifier refers to a type name
|
||||
|
||||
function Lkt_Node_P_Env_From_Vals_Internal
|
||||
(Node : Bare_Lkt_Node;
|
||||
Vals : Internal_Env_Kv_Array_Access) return Lexical_Env;
|
||||
|
||||
function Lkt_Node_P_Internal_Fetch_Referenced_Unit
|
||||
(Node : Bare_Lkt_Node; Name : String_Type) return Internal_Unit;
|
||||
-- Return the unit that this name designates. Load it if needed.
|
||||
|
||||
102
contrib/lkt/extensions/src/liblktlang-semantic_diagnostics.adb
Normal file
102
contrib/lkt/extensions/src/liblktlang-semantic_diagnostics.adb
Normal file
@@ -0,0 +1,102 @@
|
||||
with Ada.Directories; use Ada.Directories;
|
||||
with Ada.Strings.Wide_Wide_Unbounded; use Ada.Strings.Wide_Wide_Unbounded;
|
||||
with Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO;
|
||||
use Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO;
|
||||
with Ada.Text_IO;
|
||||
with Ada.Wide_Wide_Text_IO; use Ada.Wide_Wide_Text_IO;
|
||||
|
||||
with Liblktlang.Implementation.Extensions;
|
||||
use Liblktlang.Implementation.Extensions;
|
||||
with Liblktlang_Support.Slocs; use Liblktlang_Support.Slocs;
|
||||
|
||||
package body Liblktlang.Semantic_Diagnostics is
|
||||
|
||||
---------------------------
|
||||
-- Set_Solver_Debug_Mode --
|
||||
---------------------------
|
||||
|
||||
procedure Set_Solver_Debug_Mode (Enable : Boolean) is
|
||||
Unused : Boolean;
|
||||
begin
|
||||
Unused := Lkt_Node_P_Set_Solver_Debug_Mode (null, Enable);
|
||||
end Set_Solver_Debug_Mode;
|
||||
|
||||
--------------------------------------
|
||||
-- Print_Solver_Diagnostics_In_Unit --
|
||||
--------------------------------------
|
||||
|
||||
procedure Print_Solver_Diagnostics_In_Unit
|
||||
(Unit : Analysis.Analysis_Unit) is
|
||||
begin
|
||||
Print_Solver_Diagnostics_In_Node (Unit.Root);
|
||||
end Print_Solver_Diagnostics_In_Unit;
|
||||
|
||||
--------------------------------------
|
||||
-- Print_Solver_Diagnostics_In_Node --
|
||||
--------------------------------------
|
||||
|
||||
procedure Print_Solver_Diagnostics_In_Node (Node : Lkt_Node) is
|
||||
begin
|
||||
if Node.P_Xref_Entry_Point then
|
||||
for Diagnostic of Node.P_Nameres_Diagnostics loop
|
||||
Print_Solver_Diagnostic (Diagnostic);
|
||||
end loop;
|
||||
end if;
|
||||
for Child of Node.Children loop
|
||||
if not Child.Is_Null then
|
||||
Print_Solver_Diagnostics_In_Node (Child);
|
||||
end if;
|
||||
end loop;
|
||||
end Print_Solver_Diagnostics_In_Node;
|
||||
|
||||
-----------------------------
|
||||
-- Print_Solver_Diagnostic --
|
||||
-----------------------------
|
||||
|
||||
procedure Print_Solver_Diagnostic (Diag : Solver_Diagnostic)
|
||||
is
|
||||
Node : constant Lkt_Node := Location (Diag).As_Lkt_Node;
|
||||
Filename : constant String := Node.Unit.Get_Filename;
|
||||
begin
|
||||
Ada.Text_IO.Put (Simple_Name (Filename) & ":");
|
||||
Put (Node.Sloc_Range.Image & ": error: ");
|
||||
Put_Line (Render_Solver_Diagnostic (Diag));
|
||||
|
||||
Ada.Text_IO.Put (Node.Sloc_Range.Start_Line'Image & " | ");
|
||||
Put_Line (Node.Unit.Get_Line (Integer (Node.Sloc_Range.Start_Line)));
|
||||
|
||||
declare
|
||||
S : String (1 .. Integer (Node.Sloc_Range.End_Column)) :=
|
||||
(others => ' ');
|
||||
begin
|
||||
Put ((Integer (Node.Sloc_Range.Start_Line'Image'Length)) * " ");
|
||||
Ada.Text_IO.Put (" | ");
|
||||
S (Integer (Node.Sloc_Range.Start_Column) ..
|
||||
Integer (Node.Sloc_Range.End_Column - 1)) :=
|
||||
(others => '^');
|
||||
Ada.Text_IO.Put_Line (S);
|
||||
end;
|
||||
end Print_Solver_Diagnostic;
|
||||
|
||||
------------------------------
|
||||
-- Render_Solver_Diagnostic --
|
||||
------------------------------
|
||||
|
||||
function Render_Solver_Diagnostic
|
||||
(Diag : Solver_Diagnostic) return Unbounded_Text_Type
|
||||
is
|
||||
-- Index to the position of the previous "{}" pattern found in the
|
||||
-- diagnostic message pattern while rendering the diagnostic.
|
||||
Last_Index : Natural := 1;
|
||||
Result : Unbounded_Text_Type :=
|
||||
To_Unbounded_Wide_Wide_String (Message_Template (Diag));
|
||||
begin
|
||||
for Arg of Args (Diag) loop
|
||||
Last_Index := Index (Result, "{}", Last_Index);
|
||||
Replace_Slice
|
||||
(Result, Last_Index, Last_Index + 1, Arg.As_Decl.P_Full_Name);
|
||||
end loop;
|
||||
return Result;
|
||||
end Render_Solver_Diagnostic;
|
||||
|
||||
end Liblktlang.Semantic_Diagnostics;
|
||||
@@ -0,0 +1,25 @@
|
||||
with Liblktlang.Analysis; use Liblktlang.Analysis;
|
||||
with Liblktlang_Support.Text; use Liblktlang_Support.Text;
|
||||
|
||||
package Liblktlang.Semantic_Diagnostics is
|
||||
|
||||
procedure Set_Solver_Debug_Mode (Enable : Boolean);
|
||||
-- Enable or disable the solver traces for debugging purposes
|
||||
|
||||
procedure Print_Solver_Diagnostics_In_Unit (Unit : Analysis.Analysis_Unit);
|
||||
-- Traverse all nodes in ``Unit`` and print all solver diagnostics their
|
||||
-- name resolution finds.
|
||||
|
||||
procedure Print_Solver_Diagnostics_In_Node (Node : Lkt_Node);
|
||||
-- Print solver diagnostics for the name resolution of all nodes in the
|
||||
-- tree rooted at Node.
|
||||
|
||||
procedure Print_Solver_Diagnostic (Diag : Solver_Diagnostic);
|
||||
-- Print a ``Solver_Diagnostic`` to the standard output with the GNU format
|
||||
|
||||
function Render_Solver_Diagnostic
|
||||
(Diag : Solver_Diagnostic) return Unbounded_Text_Type;
|
||||
-- Create the error message of a ``Solver_Diagnostic`` from its template
|
||||
-- and arguments.
|
||||
|
||||
end Liblktlang.Semantic_Diagnostics;
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -926,13 +926,13 @@ def print_error(message: str,
|
||||
print(src_lst)
|
||||
|
||||
|
||||
def print_error_from_sem_result(sem_result: L.SemanticResult) -> None:
|
||||
def print_error_from_sem_result(sdiag: L.SolverDiagnostic) -> None:
|
||||
"""
|
||||
Emit an error from an Lkt semantic result.
|
||||
"""
|
||||
with diagnostic_context(
|
||||
Location.from_lkt_node(sem_result.node)
|
||||
Location.from_lkt_node(sdiag.location)
|
||||
):
|
||||
check_source_language(False,
|
||||
sem_result.error_message,
|
||||
sdiag.message_template.format(*sdiag.args),
|
||||
severity=Severity.non_blocking_error)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
>&2:buffer_size=0
|
||||
@@ -1,11 +0,0 @@
|
||||
class A {
|
||||
fun f_ok1(): Int = 0
|
||||
@abstract fun f_ok2(): Int
|
||||
@builtin fun f_ok3(): Int
|
||||
@external fun f_ok4(): Int
|
||||
|
||||
@invalid fun f_error1(): Int
|
||||
@invalid @abstract fun f_error2(): Int = 0
|
||||
@invalid @builtin fun f_error3(): Int = 0
|
||||
@invalid @external fun f_error3(): Int = 0
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
Resolving test.lkt
|
||||
==================
|
||||
Id <RefId "Int" test.lkt:2:18-2:21>
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Expr <NumLit test.lkt:2:24-2:25>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "Int" test.lkt:3:28-3:31>
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "Int" test.lkt:4:27-4:30>
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "Int" test.lkt:5:28-5:31>
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "Int" test.lkt:7:30-7:33>
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "Int" test.lkt:8:40-8:43>
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Expr <NumLit test.lkt:8:46-8:47>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "Int" test.lkt:9:39-9:42>
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Expr <NumLit test.lkt:9:45-9:46>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "Int" test.lkt:10:40-10:43>
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Expr <NumLit test.lkt:10:46-10:47>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
test.lkt:7:14: error: regular functions must have a body
|
||||
7 | @invalid fun f_error1(): Int
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
test.lkt:8:24: error: abstract functions cannot have a body
|
||||
8 | @invalid @abstract fun f_error2(): Int = 0
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
test.lkt:9:23: error: builtin functions cannot have a body
|
||||
9 | @invalid @builtin fun f_error3(): Int = 0
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
test.lkt:10:24: error: external functions cannot have a body
|
||||
10 | @invalid @external fun f_error3(): Int = 0
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
class MyCallable {
|
||||
fun __call__(a: Int): Bool = true
|
||||
}
|
||||
|
||||
class RecursiveCallable {
|
||||
fun __call__(a: Int): RecursiveCallable = self
|
||||
}
|
||||
|
||||
class A {
|
||||
@property
|
||||
fun pouet(): (Int) -> Bool = (i) => true
|
||||
|
||||
fun callable_array(): Array[MyCallable] = []
|
||||
|
||||
fun test(): Bool = self.pouet(12)
|
||||
fun test2(): Bool = MyCallable()(12)
|
||||
fun test3(): Bool = self.callable_array()(12)(12)
|
||||
fun test4(): RecursiveCallable =
|
||||
RecursiveCallable()(12)(12)(12)(12)(12)(12)(12)(12)(12)(12)(12)(12)
|
||||
(12)(12)
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
Resolving test.lkt
|
||||
==================
|
||||
Id <RefId "Int" test.lkt:2:21-2:24>
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "Bool" test.lkt:2:27-2:31>
|
||||
references <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Id <RefId "true" test.lkt:2:34-2:38>
|
||||
references <EnumLitDecl prelude: "true">
|
||||
|
||||
Expr <RefId "true" test.lkt:2:34-2:38>
|
||||
has type <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Id <RefId "Int" test.lkt:6:21-6:24>
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "RecursiveCallable" test.lkt:6:27-6:44>
|
||||
references <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Id <RefId "self" test.lkt:6:47-6:51>
|
||||
references <SelfDecl "self" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <RefId "self" test.lkt:6:47-6:51>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Id <RefId "Int" test.lkt:11:19-11:22>
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "Bool" test.lkt:11:27-11:31>
|
||||
references <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Id <RefId "true" test.lkt:11:41-11:45>
|
||||
references <EnumLitDecl prelude: "true">
|
||||
|
||||
Expr <RefId "true" test.lkt:11:41-11:45>
|
||||
has type <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Expr <LambdaExpr test.lkt:11:34-11:45>
|
||||
has type <FunctionType prelude: "(Int) -> Bool">
|
||||
|
||||
Id <RefId "Array" test.lkt:13:27-13:32>
|
||||
references <GenericDecl prelude: "Array">
|
||||
|
||||
Id <RefId "MyCallable" test.lkt:13:33-13:43>
|
||||
references <ClassDecl "MyCallable" test.lkt:1:1-3:2>
|
||||
|
||||
Expr <ArrayLiteral test.lkt:13:47-13:49>
|
||||
has type <InstantiatedGenericType prelude: "Array[MyCallable]">
|
||||
|
||||
Id <RefId "Bool" test.lkt:15:17-15:21>
|
||||
references <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Id <RefId "self" test.lkt:15:24-15:28>
|
||||
references <SelfDecl "self" test.lkt:9:1-21:2>
|
||||
|
||||
Expr <RefId "self" test.lkt:15:24-15:28>
|
||||
has type <ClassDecl "A" test.lkt:9:1-21:2>
|
||||
|
||||
Id <RefId "pouet" test.lkt:15:29-15:34>
|
||||
references <FunDecl "pouet" test.lkt:11:5-11:45>
|
||||
|
||||
Expr <RefId "pouet" test.lkt:15:29-15:34>
|
||||
has type <FunctionType prelude: "(Int) -> Bool">
|
||||
|
||||
Expr <DotExpr test.lkt:15:24-15:34>
|
||||
has type <FunctionType prelude: "(Int) -> Bool">
|
||||
|
||||
Expr <NumLit test.lkt:15:35-15:37>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:15:24-15:38>
|
||||
has type <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Id <RefId "Bool" test.lkt:16:18-16:22>
|
||||
references <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Id <RefId "MyCallable" test.lkt:16:25-16:35>
|
||||
references <ClassDecl "MyCallable" test.lkt:1:1-3:2>
|
||||
|
||||
Expr <CallExpr test.lkt:16:25-16:37>
|
||||
has type <ClassDecl "MyCallable" test.lkt:1:1-3:2>
|
||||
|
||||
Expr <NumLit test.lkt:16:38-16:40>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:16:25-16:41>
|
||||
has type <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Id <RefId "Bool" test.lkt:17:18-17:22>
|
||||
references <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Id <RefId "self" test.lkt:17:25-17:29>
|
||||
references <SelfDecl "self" test.lkt:9:1-21:2>
|
||||
|
||||
Expr <RefId "self" test.lkt:17:25-17:29>
|
||||
has type <ClassDecl "A" test.lkt:9:1-21:2>
|
||||
|
||||
Id <RefId "callable_array" test.lkt:17:30-17:44>
|
||||
references <FunDecl "callable_array" test.lkt:13:5-13:49>
|
||||
|
||||
Expr <RefId "callable_array" test.lkt:17:30-17:44>
|
||||
has type <FunctionType prelude: "() -> Array[MyCallable]">
|
||||
|
||||
Expr <DotExpr test.lkt:17:25-17:44>
|
||||
has type <FunctionType prelude: "() -> Array[MyCallable]">
|
||||
|
||||
Expr <CallExpr test.lkt:17:25-17:46>
|
||||
has type <InstantiatedGenericType prelude: "Array[MyCallable]">
|
||||
|
||||
Expr <NumLit test.lkt:17:47-17:49>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:17:25-17:50>
|
||||
has type <ClassDecl "MyCallable" test.lkt:1:1-3:2>
|
||||
|
||||
Expr <NumLit test.lkt:17:51-17:53>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:17:25-17:54>
|
||||
has type <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Id <RefId "RecursiveCallable" test.lkt:18:18-18:35>
|
||||
references <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Id <RefId "RecursiveCallable" test.lkt:19:9-19:26>
|
||||
references <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:28>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:19:29-19:31>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:32>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:19:33-19:35>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:36>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:19:37-19:39>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:40>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:19:41-19:43>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:44>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:19:45-19:47>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:48>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:19:49-19:51>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:52>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:19:53-19:55>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:56>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:19:57-19:59>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:60>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:19:61-19:63>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:64>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:19:65-19:67>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:68>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:19:69-19:71>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:72>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:19:73-19:75>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-19:76>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:20:14-20:16>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-20:17>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
Expr <NumLit test.lkt:20:18-20:20>
|
||||
has type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <CallExpr test.lkt:19:9-20:21>
|
||||
has type <ClassDecl "RecursiveCallable" test.lkt:5:1-7:2>
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
# Test that an error message is emitted in the case of an ambiguously typed
|
||||
# expression.
|
||||
|
||||
@invalid val a = "hello"
|
||||
@@ -1,6 +0,0 @@
|
||||
Resolving test.lkt
|
||||
==================
|
||||
test.lkt:4:18: error: ambiguous type for expression
|
||||
4 | @invalid val a = "hello"
|
||||
| ^^^^^^^
|
||||
|
||||
8
testsuite/tests/contrib/lkt_semantic/anyof/test.lkt
Normal file
8
testsuite/tests/contrib/lkt_semantic/anyof/test.lkt
Normal file
@@ -0,0 +1,8 @@
|
||||
class FooNode implements Node[FooNode] {}
|
||||
class Child : FooNode {}
|
||||
|
||||
val valid1 = 1 in 1 | 2 | 3
|
||||
val valid2 = Child() in FooNode() | Child() | null
|
||||
|
||||
val one_invalid = 1 in 1 | 2 | "3"
|
||||
val all_invalid = 1 in "1" | "2" | "3"
|
||||
116
testsuite/tests/contrib/lkt_semantic/anyof/test.out
Normal file
116
testsuite/tests/contrib/lkt_semantic/anyof/test.out
Normal file
@@ -0,0 +1,116 @@
|
||||
Resolving test.lkt
|
||||
==================
|
||||
Id <RefId "Node" test.lkt:1:26-1:30>
|
||||
has_type None
|
||||
references <TraitDecl prelude: "Node[T]">
|
||||
|
||||
Id <RefId "FooNode" test.lkt:1:31-1:38>
|
||||
has_type None
|
||||
references <ClassDecl "FooNode" test.lkt:1:1-1:42>
|
||||
|
||||
Id <RefId "FooNode" test.lkt:2:15-2:22>
|
||||
has_type None
|
||||
references <ClassDecl "FooNode" test.lkt:1:1-1:42>
|
||||
|
||||
Decl <ValDecl "valid1" test.lkt:4:1-4:28>
|
||||
has_type <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Expr <AnyOf test.lkt:4:14-4:28>
|
||||
has_type <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Expr <NumLit test.lkt:4:14-4:15>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <NumLit test.lkt:4:19-4:20>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <NumLit test.lkt:4:23-4:24>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <NumLit test.lkt:4:27-4:28>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Decl <ValDecl "valid2" test.lkt:5:1-5:51>
|
||||
has_type <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Expr <AnyOf test.lkt:5:14-5:51>
|
||||
has_type <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Expr <CallExpr test.lkt:5:14-5:21>
|
||||
has_type <ClassDecl "Child" test.lkt:2:1-2:25>
|
||||
|
||||
Id <RefId "Child" test.lkt:5:14-5:19>
|
||||
has_type <FunctionType "() -> Child" test.lkt>
|
||||
references <ClassDecl "Child" test.lkt:2:1-2:25>
|
||||
|
||||
Expr <CallExpr test.lkt:5:25-5:34>
|
||||
has_type <ClassDecl "FooNode" test.lkt:1:1-1:42>
|
||||
|
||||
Id <RefId "FooNode" test.lkt:5:25-5:32>
|
||||
has_type <FunctionType "() -> FooNode" test.lkt>
|
||||
references <ClassDecl "FooNode" test.lkt:1:1-1:42>
|
||||
|
||||
Expr <CallExpr test.lkt:5:37-5:44>
|
||||
has_type <ClassDecl "Child" test.lkt:2:1-2:25>
|
||||
|
||||
Id <RefId "Child" test.lkt:5:37-5:42>
|
||||
has_type <FunctionType "() -> Child" test.lkt>
|
||||
references <ClassDecl "Child" test.lkt:2:1-2:25>
|
||||
|
||||
Expr <NullLit test.lkt:5:47-5:51>
|
||||
has_type <ClassDecl "Child" test.lkt:2:1-2:25>
|
||||
|
||||
<ValDecl "one_invalid" test.lkt:7:1-7:35> failed nameres:
|
||||
test.lkt:7:32-7:35: error: expected Int, got String
|
||||
7 | val one_invalid = 1 in 1 | 2 | "3"
|
||||
| ^^^
|
||||
|
||||
Decl <ValDecl "one_invalid" test.lkt:7:1-7:35>
|
||||
has_type None
|
||||
|
||||
Expr <AnyOf test.lkt:7:19-7:35>
|
||||
has_type None
|
||||
|
||||
Expr <NumLit test.lkt:7:19-7:20>
|
||||
has_type None
|
||||
|
||||
Expr <NumLit test.lkt:7:24-7:25>
|
||||
has_type None
|
||||
|
||||
Expr <NumLit test.lkt:7:28-7:29>
|
||||
has_type None
|
||||
|
||||
Expr <SingleLineStringLit test.lkt:7:32-7:35>
|
||||
has_type None
|
||||
|
||||
<ValDecl "all_invalid" test.lkt:8:1-8:39> failed nameres:
|
||||
test.lkt:8:24-8:27: error: expected Int, got String
|
||||
8 | val all_invalid = 1 in "1" | "2" | "3"
|
||||
| ^^^
|
||||
|
||||
test.lkt:8:30-8:33: error: expected Int, got String
|
||||
8 | val all_invalid = 1 in "1" | "2" | "3"
|
||||
| ^^^
|
||||
|
||||
test.lkt:8:36-8:39: error: expected Int, got String
|
||||
8 | val all_invalid = 1 in "1" | "2" | "3"
|
||||
| ^^^
|
||||
|
||||
Decl <ValDecl "all_invalid" test.lkt:8:1-8:39>
|
||||
has_type None
|
||||
|
||||
Expr <AnyOf test.lkt:8:19-8:39>
|
||||
has_type None
|
||||
|
||||
Expr <NumLit test.lkt:8:19-8:20>
|
||||
has_type None
|
||||
|
||||
Expr <SingleLineStringLit test.lkt:8:24-8:27>
|
||||
has_type None
|
||||
|
||||
Expr <SingleLineStringLit test.lkt:8:30-8:33>
|
||||
has_type None
|
||||
|
||||
Expr <SingleLineStringLit test.lkt:8:36-8:39>
|
||||
has_type None
|
||||
|
||||
23
testsuite/tests/contrib/lkt_semantic/array/test.lkt
Normal file
23
testsuite/tests/contrib/lkt_semantic/array/test.lkt
Normal file
@@ -0,0 +1,23 @@
|
||||
class A {}
|
||||
class B : A {}
|
||||
class C : A {}
|
||||
|
||||
val arr : Array[Int] = [0, 1, 2]
|
||||
val empty : Array[Int] = []: Int
|
||||
|
||||
val i1 = arr[0]
|
||||
|
||||
val litindex : Int = [1, 2, 3][0]
|
||||
|
||||
val common_type = [B(), C()]
|
||||
|
||||
val propagation1 : Array[A] = [null]
|
||||
val propagation2 : A = [null][0]
|
||||
val propagation3 = [null, A()]
|
||||
|
||||
val invalid1 : Array[Int] = ["", "", ""]
|
||||
val invalid2 = [null]
|
||||
val invalid3 = [A(), 1, ""]
|
||||
|
||||
val mapped = arr.map[Int]((i: Int) => i + 1)
|
||||
val filtered = arr.filter((i: Int) => i == 1)
|
||||
316
testsuite/tests/contrib/lkt_semantic/array/test.out
Normal file
316
testsuite/tests/contrib/lkt_semantic/array/test.out
Normal file
@@ -0,0 +1,316 @@
|
||||
Resolving test.lkt
|
||||
==================
|
||||
Id <RefId "A" test.lkt:2:11-2:12>
|
||||
has_type None
|
||||
references <ClassDecl "A" test.lkt:1:1-1:11>
|
||||
|
||||
Id <RefId "A" test.lkt:3:11-3:12>
|
||||
has_type None
|
||||
references <ClassDecl "A" test.lkt:1:1-1:11>
|
||||
|
||||
Decl <ValDecl "arr" test.lkt:5:1-5:33>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
|
||||
Id <RefId "Array" test.lkt:5:11-5:16>
|
||||
has_type None
|
||||
references <StructDecl prelude: "Array[T]">
|
||||
|
||||
Id <RefId "Int" test.lkt:5:17-5:20>
|
||||
has_type None
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Expr <ArrayLiteral test.lkt:5:24-5:33>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
|
||||
Expr <NumLit test.lkt:5:25-5:26>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <NumLit test.lkt:5:28-5:29>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <NumLit test.lkt:5:31-5:32>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Decl <ValDecl "empty" test.lkt:6:1-6:33>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
|
||||
Id <RefId "Array" test.lkt:6:13-6:18>
|
||||
has_type None
|
||||
references <StructDecl prelude: "Array[T]">
|
||||
|
||||
Id <RefId "Int" test.lkt:6:19-6:22>
|
||||
has_type None
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Expr <ArrayLiteral test.lkt:6:26-6:33>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
|
||||
Id <RefId "Int" test.lkt:6:30-6:33>
|
||||
has_type None
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Decl <ValDecl "i1" test.lkt:8:1-8:16>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <SubscriptExpr test.lkt:8:10-8:16>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "arr" test.lkt:8:10-8:13>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
references <ValDecl "arr" test.lkt:5:1-5:33>
|
||||
|
||||
Expr <NumLit test.lkt:8:14-8:15>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Decl <ValDecl "litindex" test.lkt:10:1-10:34>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "Int" test.lkt:10:16-10:19>
|
||||
has_type None
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Expr <SubscriptExpr test.lkt:10:22-10:34>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <ArrayLiteral test.lkt:10:22-10:31>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
|
||||
Expr <NumLit test.lkt:10:23-10:24>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <NumLit test.lkt:10:26-10:27>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <NumLit test.lkt:10:29-10:30>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Expr <NumLit test.lkt:10:32-10:33>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Decl <ValDecl "common_type" test.lkt:12:1-12:29>
|
||||
has_type <StructDecl prelude: "Array[A]">
|
||||
|
||||
Expr <ArrayLiteral test.lkt:12:19-12:29>
|
||||
has_type <StructDecl prelude: "Array[A]">
|
||||
|
||||
Expr <CallExpr test.lkt:12:20-12:23>
|
||||
has_type <ClassDecl "B" test.lkt:2:1-2:15>
|
||||
|
||||
Id <RefId "B" test.lkt:12:20-12:21>
|
||||
has_type <FunctionType "() -> B" test.lkt>
|
||||
references <ClassDecl "B" test.lkt:2:1-2:15>
|
||||
|
||||
Expr <CallExpr test.lkt:12:25-12:28>
|
||||
has_type <ClassDecl "C" test.lkt:3:1-3:15>
|
||||
|
||||
Id <RefId "C" test.lkt:12:25-12:26>
|
||||
has_type <FunctionType "() -> C" test.lkt>
|
||||
references <ClassDecl "C" test.lkt:3:1-3:15>
|
||||
|
||||
Decl <ValDecl "propagation1" test.lkt:14:1-14:37>
|
||||
has_type <StructDecl prelude: "Array[A]">
|
||||
|
||||
Id <RefId "Array" test.lkt:14:20-14:25>
|
||||
has_type None
|
||||
references <StructDecl prelude: "Array[T]">
|
||||
|
||||
Id <RefId "A" test.lkt:14:26-14:27>
|
||||
has_type None
|
||||
references <ClassDecl "A" test.lkt:1:1-1:11>
|
||||
|
||||
Expr <ArrayLiteral test.lkt:14:31-14:37>
|
||||
has_type <StructDecl prelude: "Array[A]">
|
||||
|
||||
Expr <NullLit test.lkt:14:32-14:36>
|
||||
has_type <ClassDecl "A" test.lkt:1:1-1:11>
|
||||
|
||||
Decl <ValDecl "propagation2" test.lkt:15:1-15:33>
|
||||
has_type <ClassDecl "A" test.lkt:1:1-1:11>
|
||||
|
||||
Id <RefId "A" test.lkt:15:20-15:21>
|
||||
has_type None
|
||||
references <ClassDecl "A" test.lkt:1:1-1:11>
|
||||
|
||||
Expr <SubscriptExpr test.lkt:15:24-15:33>
|
||||
has_type <ClassDecl "A" test.lkt:1:1-1:11>
|
||||
|
||||
Expr <ArrayLiteral test.lkt:15:24-15:30>
|
||||
has_type <StructDecl prelude: "Array[A]">
|
||||
|
||||
Expr <NullLit test.lkt:15:25-15:29>
|
||||
has_type <ClassDecl "A" test.lkt:1:1-1:11>
|
||||
|
||||
Expr <NumLit test.lkt:15:31-15:32>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Decl <ValDecl "propagation3" test.lkt:16:1-16:31>
|
||||
has_type <StructDecl prelude: "Array[A]">
|
||||
|
||||
Expr <ArrayLiteral test.lkt:16:20-16:31>
|
||||
has_type <StructDecl prelude: "Array[A]">
|
||||
|
||||
Expr <NullLit test.lkt:16:21-16:25>
|
||||
has_type <ClassDecl "A" test.lkt:1:1-1:11>
|
||||
|
||||
Expr <CallExpr test.lkt:16:27-16:30>
|
||||
has_type <ClassDecl "A" test.lkt:1:1-1:11>
|
||||
|
||||
Id <RefId "A" test.lkt:16:27-16:28>
|
||||
has_type <FunctionType "() -> A" test.lkt>
|
||||
references <ClassDecl "A" test.lkt:1:1-1:11>
|
||||
|
||||
<ValDecl "invalid1" test.lkt:18:1-18:41> failed nameres:
|
||||
test.lkt:18:29-18:41: error: expected Array[Int], got Array[String]
|
||||
18 | val invalid1 : Array[Int] = ["", "", ""]
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
Decl <ValDecl "invalid1" test.lkt:18:1-18:41>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
|
||||
Id <RefId "Array" test.lkt:18:16-18:21>
|
||||
has_type None
|
||||
references <StructDecl prelude: "Array[T]">
|
||||
|
||||
Id <RefId "Int" test.lkt:18:22-18:25>
|
||||
has_type None
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Expr <ArrayLiteral test.lkt:18:29-18:41>
|
||||
has_type None
|
||||
|
||||
Expr <SingleLineStringLit test.lkt:18:30-18:32>
|
||||
has_type None
|
||||
|
||||
Expr <SingleLineStringLit test.lkt:18:34-18:36>
|
||||
has_type None
|
||||
|
||||
Expr <SingleLineStringLit test.lkt:18:38-18:40>
|
||||
has_type None
|
||||
|
||||
<ValDecl "invalid2" test.lkt:19:1-19:22> failed nameres:
|
||||
test.lkt:19:17-19:21: error: could not determine type
|
||||
19 | val invalid2 = [null]
|
||||
| ^^^^
|
||||
|
||||
test.lkt:19:5-19:13: error: could not determine type
|
||||
19 | val invalid2 = [null]
|
||||
| ^^^^^^^^
|
||||
|
||||
Decl <ValDecl "invalid2" test.lkt:19:1-19:22>
|
||||
has_type None
|
||||
|
||||
Expr <ArrayLiteral test.lkt:19:16-19:22>
|
||||
has_type None
|
||||
|
||||
Expr <NullLit test.lkt:19:17-19:21>
|
||||
has_type None
|
||||
|
||||
<ValDecl "invalid3" test.lkt:20:1-20:28> failed nameres:
|
||||
test.lkt:20:17-20:20: error: expected Int, got A
|
||||
20 | val invalid3 = [A(), 1, ""]
|
||||
| ^^^
|
||||
|
||||
test.lkt:20:25-20:27: error: expected Int, got String
|
||||
20 | val invalid3 = [A(), 1, ""]
|
||||
| ^^
|
||||
|
||||
Decl <ValDecl "invalid3" test.lkt:20:1-20:28>
|
||||
has_type None
|
||||
|
||||
Expr <ArrayLiteral test.lkt:20:16-20:28>
|
||||
has_type None
|
||||
|
||||
Expr <CallExpr test.lkt:20:17-20:20>
|
||||
has_type None
|
||||
|
||||
Id <RefId "A" test.lkt:20:17-20:18>
|
||||
has_type None
|
||||
references None
|
||||
|
||||
Expr <NumLit test.lkt:20:22-20:23>
|
||||
has_type None
|
||||
|
||||
Expr <SingleLineStringLit test.lkt:20:25-20:27>
|
||||
has_type None
|
||||
|
||||
Decl <ValDecl "mapped" test.lkt:22:1-22:45>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
|
||||
Expr <CallExpr test.lkt:22:14-22:45>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
|
||||
Expr <GenericInstantiation test.lkt:22:14-22:26>
|
||||
has_type <FunctionType prelude: "((Int) -> Int) -> Array[Int]">
|
||||
|
||||
Expr <DotExpr test.lkt:22:14-22:21>
|
||||
has_type <FunctionType prelude: "((Int) -> U) -> Array[U]">
|
||||
|
||||
Id <RefId "arr" test.lkt:22:14-22:17>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
references <ValDecl "arr" test.lkt:5:1-5:33>
|
||||
|
||||
Id <RefId "map" test.lkt:22:18-22:21>
|
||||
has_type <FunctionType prelude: "((Int) -> U) -> Array[U]">
|
||||
references <FunDecl prelude: "map[U]">
|
||||
|
||||
Id <RefId "Int" test.lkt:22:22-22:25>
|
||||
has_type None
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Expr <LambdaExpr test.lkt:22:27-22:44>
|
||||
has_type <FunctionType prelude: "(Int) -> Int">
|
||||
|
||||
Decl <LambdaArgDecl "i" test.lkt:22:28-22:34>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "Int" test.lkt:22:31-22:34>
|
||||
has_type None
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Expr <BinOp test.lkt:22:39-22:44>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "i" test.lkt:22:39-22:40>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
references <LambdaArgDecl "i" test.lkt:22:28-22:34>
|
||||
|
||||
Expr <NumLit test.lkt:22:43-22:44>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Decl <ValDecl "filtered" test.lkt:23:1-23:46>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
|
||||
Expr <CallExpr test.lkt:23:16-23:46>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
|
||||
Expr <DotExpr test.lkt:23:16-23:26>
|
||||
has_type <FunctionType prelude: "((Int) -> Bool) -> Array[Int]">
|
||||
|
||||
Id <RefId "arr" test.lkt:23:16-23:19>
|
||||
has_type <StructDecl prelude: "Array[Int]">
|
||||
references <ValDecl "arr" test.lkt:5:1-5:33>
|
||||
|
||||
Id <RefId "filter" test.lkt:23:20-23:26>
|
||||
has_type <FunctionType prelude: "((Int) -> Bool) -> Array[Int]">
|
||||
references <FunDecl prelude: "filter">
|
||||
|
||||
Expr <LambdaExpr test.lkt:23:27-23:45>
|
||||
has_type <FunctionType prelude: "(Int) -> Bool">
|
||||
|
||||
Decl <LambdaArgDecl "i" test.lkt:23:28-23:34>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Id <RefId "Int" test.lkt:23:31-23:34>
|
||||
has_type None
|
||||
references <StructDecl prelude: "Int">
|
||||
|
||||
Expr <BinOp test.lkt:23:39-23:45>
|
||||
has_type <EnumTypeDecl prelude: "Bool">
|
||||
|
||||
Id <RefId "i" test.lkt:23:39-23:40>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
references <LambdaArgDecl "i" test.lkt:23:28-23:34>
|
||||
|
||||
Expr <NumLit test.lkt:23:44-23:45>
|
||||
has_type <StructDecl prelude: "Int">
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user