From 3f01e21ca4ab12c86f7e9c6257beec3ea51ea6d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Samson?= Date: Sat, 4 Mar 2023 17:21:36 +0100 Subject: [PATCH] Make document symbols more resilient (#820) Do not crash on incomplete typespecs --- .../providers/document_symbols.ex | 6 ++++- .../test/providers/document_symbols_test.exs | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/apps/language_server/lib/language_server/providers/document_symbols.ex b/apps/language_server/lib/language_server/providers/document_symbols.ex index 9ee3263de..a279fe2fd 100644 --- a/apps/language_server/lib/language_server/providers/document_symbols.ex +++ b/apps/language_server/lib/language_server/providers/document_symbols.ex @@ -169,7 +169,8 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do # Types defp extract_symbol(_current_module, {:@, location, [{type_kind, _, type_expression}]}) - when type_kind in [:type, :typep, :opaque, :callback, :macrocallback] do + when type_kind in [:type, :typep, :opaque, :callback, :macrocallback] and + not is_nil(type_expression) do {type_name, type_head_location} = case type_expression do [{:"::", _, [{_, type_head_location, _} = type_head | _]}] -> @@ -177,6 +178,9 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do [{:when, _, [{:"::", _, [{_, type_head_location, _} = type_head, _]}, _]}] -> {Macro.to_string(type_head), type_head_location} + + [{_, type_head_location, _} = type_head | _] -> + {Macro.to_string(type_head), type_head_location} end type_name = diff --git a/apps/language_server/test/providers/document_symbols_test.exs b/apps/language_server/test/providers/document_symbols_test.exs index e7b235a1c..f8c0f88fb 100644 --- a/apps/language_server/test/providers/document_symbols_test.exs +++ b/apps/language_server/test/providers/document_symbols_test.exs @@ -1172,6 +1172,8 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do @opaque my_simple_opaque :: integer @type my_with_args(key, value) :: [{key, value}] @type my_with_args_when(key, value) :: [{key, value}] when value: integer + @type abc + @type end """ @@ -1216,6 +1218,16 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do children: [], kind: 5, name: "@type my_with_args_when(key, value)" + }, + %Protocol.DocumentSymbol{ + children: [], + kind: 5, + name: "@type abc" + }, + %Protocol.DocumentSymbol{ + children: [], + kind: 14, + name: "@type" } ], kind: 2, @@ -1235,6 +1247,8 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do @opaque my_simple_opaque :: integer @type my_with_args(key, value) :: [{key, value}] @type my_with_args_when(key, value) :: [{key, value}] when value: integer + @type abc + @type end """ @@ -1279,6 +1293,16 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do kind: 5, name: "@type my_with_args_when(key, value)", containerName: "MyModule" + }, + %Protocol.SymbolInformation{ + kind: 5, + name: "@type abc", + containerName: "MyModule" + }, + %Protocol.SymbolInformation{ + kind: 14, + name: "@type", + containerName: "MyModule" } ]} = DocumentSymbols.symbols(uri, text, false) end