Skip to content

Commit

Permalink
Merge remote branch 'origin/master' into edge
Browse files Browse the repository at this point in the history
  • Loading branch information
automatic-merge committed Jul 10, 2024
2 parents 0e6a3ee + 0a9d559 commit bcceff7
Show file tree
Hide file tree
Showing 17 changed files with 528 additions and 330 deletions.
41 changes: 41 additions & 0 deletions source/ada/lsp-ada_completions-filters.adb
Original file line number Diff line number Diff line change
Expand Up @@ -309,4 +309,45 @@ package body LSP.Ada_Completions.Filters is
return Self.Is_Comma.Value;
end Is_Comma;

-------------------------
-- Is_Open_Parenthesis --
-------------------------

function Is_Open_Parenthesis
(Self : in out Filter'Class;
Exclude_Trivia : Boolean := True) return Boolean
is
begin
if not Self.Is_Open_Parenthesis.Is_Set then
declare
use all type Libadalang.Common.Token_Kind;
use all type Libadalang.Common.Token_Reference;

Token_Kind : constant Libadalang.Common.Token_Kind := Self.Token.Data.Kind;
begin
Self.Is_Open_Parenthesis := (True, Token_Kind = Ada_Par_Open);

-- The curent token is not an open parenthesis: check for the previous
-- one if we are on a trivia.
if not Self.Is_Open_Parenthesis.Value
and then (Self.Token.Is_Trivia and then Exclude_Trivia)
then
declare
Previous_Token :
constant Libadalang.Common.Token_Reference :=
Self.Token.Previous (Exclude_Trivia => True);
begin
Self.Is_Open_Parenthesis :=
(True,
Previous_Token /= Libadalang.Common.No_Token
and then Previous_Token.Data.Kind =
Ada_Par_Open);
end;
end if;
end;
end if;

return Self.Is_Open_Parenthesis.Value;
end Is_Open_Parenthesis;

end LSP.Ada_Completions.Filters;
25 changes: 17 additions & 8 deletions source/ada/lsp-ada_completions-filters.ads
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,26 @@ package LSP.Ada_Completions.Filters is
function Is_Comma (Self : in out Filter'Class) return Boolean;
-- Check if we complete right after ","

function Is_Open_Parenthesis
(Self : in out Filter'Class;
Exclude_Trivia : Boolean := True) return Boolean;
-- Check if we complete right after "(".
-- If Exclude_Trivia is True and if the current token is a trivia
-- (e.g: whitespace), the first previous non-trivia token ill be
-- checked too.

private

type Filter is tagged limited record
Token : Libadalang.Common.Token_Reference;
Node : Libadalang.Analysis.Ada_Node;
Is_End_Label : LSP.Structures.Boolean_Optional;
Is_Numeric_Literal : LSP.Structures.Boolean_Optional;
Is_Attribute : LSP.Structures.Boolean_Optional;
Is_Aspect : LSP.Structures.Boolean_Optional;
Is_Semicolon : LSP.Structures.Boolean_Optional;
Is_Comma : LSP.Structures.Boolean_Optional;
Token : Libadalang.Common.Token_Reference;
Node : Libadalang.Analysis.Ada_Node;
Is_End_Label : LSP.Structures.Boolean_Optional;
Is_Numeric_Literal : LSP.Structures.Boolean_Optional;
Is_Attribute : LSP.Structures.Boolean_Optional;
Is_Aspect : LSP.Structures.Boolean_Optional;
Is_Semicolon : LSP.Structures.Boolean_Optional;
Is_Comma : LSP.Structures.Boolean_Optional;
Is_Open_Parenthesis : LSP.Structures.Boolean_Optional;
end record;

end LSP.Ada_Completions.Filters;
41 changes: 27 additions & 14 deletions source/ada/lsp-ada_completions-names.adb
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
with Langkit_Support.Errors;

with VSS.Strings;
with VSS.Transformers.Caseless;

with LSP.Ada_Completions.Filters;
with LSP.Enumerations;
with LSP.Search;
with LSP.Utils;

package body LSP.Ada_Completions.Names is

Expand Down Expand Up @@ -114,11 +116,13 @@ package body LSP.Ada_Completions.Names is
return;
end if;

-- Don't complete numeric literals, attributes nor end labels or aspects
-- Don't complete numeric literals, attributes, end labels, aspects
-- or right after typing an open parenthesis
if Filter.Is_Numeric_Literal
or else Filter.Is_Attribute_Ref
or else Filter.Is_Aspect
or else Filter.Is_End_Label
or else Filter.Is_Open_Parenthesis
then
return;
end if;
Expand Down Expand Up @@ -156,9 +160,24 @@ package body LSP.Ada_Completions.Names is

declare
use Libadalang.Analysis;

Prefix : constant VSS.Strings.Virtual_String :=
VSS.Strings.To_Virtual_String (Node.Text);
use Libadalang.Common;

Word : constant VSS.Strings.Virtual_String :=
VSS.Strings.To_Virtual_String
(if
Libadalang.Common.Is_Trivia (Token)
or else Token.Data.Kind = Libadalang.Common.Ada_Dot
then ""
else Libadalang.Common.Text (Token));
Canonical_Prefix : constant VSS.Strings.Virtual_String :=
LSP.Utils.Canonicalize (Word);
Pattern : constant LSP.Search.Search_Pattern'Class :=
LSP.Search.Build
(Pattern => Canonical_Prefix,
Case_Sensitive => False,
Whole_Word => False,
Negate => False,
Kind => LSP.Enumerations.Start_Word_Text);
Raw_Completions : constant Completion_Item_Iterator :=
Dotted_Node.P_Complete;

Expand All @@ -167,28 +186,22 @@ package body LSP.Ada_Completions.Names is
Completion_Count : Natural := Natural (Result.items.Length);
Name : VSS.Strings.Virtual_String;
Underscore : constant VSS.Strings.Virtual_String := "_";

begin
while Next (Raw_Completions, Item) loop
BD := Decl (Item).As_Basic_Decl;

if not BD.Is_Null then
for DN of BD.P_Defining_Names loop

Name := VSS.Strings.To_Virtual_String
(DN.P_Relative_Name.Text);

if Name.Ends_With (Underscore) then
-- Skip `root_types_` until UB30-020 is fixed.
null;

-- If we are not completing a dotted name, filter the
-- raw completion results by the node's prefix.
elsif Dotted_Node.Kind in
Libadalang.Common.Ada_Dotted_Name_Range
or else Name.Starts_With
(Prefix,
VSS.Transformers.Caseless.To_Identifier_Caseless)
then
-- Filter the raw completion results by the node's prefix.
elsif Pattern.Match (Name) then
Completion_Count := Completion_Count + 1;

Names.Include
Expand Down
45 changes: 18 additions & 27 deletions source/ada/lsp-ada_handlers-invisibles.adb
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@
-- of the license. --
------------------------------------------------------------------------------

with GNATCOLL;
with GNATCOLL.Utils;
with GNATCOLL.VFS;

with Langkit_Support.Text;
with VSS.Strings;

with LSP.Enumerations;
Expand All @@ -42,6 +39,8 @@ package body LSP.Ada_Handlers.Invisibles is
Result : in out LSP.Structures.CompletionList)
is
pragma Unreferenced (Result);
use all type Libadalang.Common.Token_Kind;
use all type Libadalang.Common.Token_Reference;
use type Ada.Containers.Count_Type;

procedure On_Inaccessible_Name
Expand Down Expand Up @@ -80,17 +79,23 @@ package body LSP.Ada_Handlers.Invisibles is
end if;
end On_Inaccessible_Name;

function Dummy_Canceled return Boolean is (False);
Previous_Tok : constant Libadalang.Common.Token_Reference :=
Libadalang.Common.Previous (Token, Exclude_Trivia => True);
Dot_Token : constant Libadalang.Common.Token_Data_Type :=
Libadalang.Common.Data
(if Libadalang.Common.Is_Trivia (Token)
and then Previous_Tok /= Libadalang.Common.No_Token
then Previous_Tok
else Token);

Unit_Prefix : VSS.Strings.Virtual_String;
-- The unit prefix specified before the point of completion, if any
-- (e.g: "Ada.Text_IO" when completing "Ada.Text_IO.").
-- Used to filter invisible completion items: if there is a unit prefix,
-- we want to show only the public symbols declared in this
-- non-visible unit.
function Dummy_Canceled return Boolean is (False);

begin
if Filter.Is_Numeric_Literal
if Libadalang.Common.Kind (Dot_Token) = Ada_Dot then
-- Don't provide invisible completion after a dot: it's
-- handled by the default LAL completion provider.
return;
elsif Filter.Is_Numeric_Literal
or else Filter.Is_Attribute_Ref
or else Filter.Is_Aspect
or else Filter.Is_End_Label
Expand All @@ -107,6 +112,7 @@ package body LSP.Ada_Handlers.Invisibles is
if Node.Is_Null or else
(not Node.Parent.Is_Null and then Node.Parent.Kind in
Libadalang.Common.Ada_Defining_Name_Range
| Libadalang.Common.Ada_Dotted_Name_Range
| Libadalang.Common.Ada_Ada_Node_List_Range)
then
return;
Expand All @@ -118,20 +124,6 @@ package body LSP.Ada_Handlers.Invisibles is
return;
end if;

-- We are completing a dotted-name: check if we have a unit prefix
if Node.Kind in Libadalang.Common.Ada_Dotted_Name_Range then
declare
Prefix : constant String :=
Langkit_Support.Text.To_UTF8 (Node.Text);
Dot_Idx : Integer := -1;
begin
Dot_Idx := GNATCOLL.Utils.Find_Char (Prefix, '.');
Unit_Prefix :=
VSS.Strings.Conversions.To_Virtual_String
(Prefix (Prefix'First .. Dot_Idx - 1));
end;
end if;

declare
Word : constant VSS.Strings.Virtual_String :=
VSS.Strings.To_Virtual_String
Expand All @@ -155,8 +147,7 @@ package body LSP.Ada_Handlers.Invisibles is
Self.Context.Get_Any_Symbol
(Pattern => Pattern,
Only_Public => True,
Callback => On_Inaccessible_Name'Access,
Unit_Prefix => Unit_Prefix);
Callback => On_Inaccessible_Name'Access);

for Doc of Self.Handler.Open_Documents loop
Doc.Get_Any_Symbol
Expand Down
Loading

0 comments on commit bcceff7

Please sign in to comment.