@@ -158,7 +158,7 @@ defmodule ElixirLS.LanguageServer.Build do
158
158
Code . put_compiler_option ( :no_warn_undefined , :all )
159
159
160
160
# We can get diagnostics if Mixfile fails to load
161
- { status , diagnostics } =
161
+ { mixfile_status , mixfile_diagnostics } =
162
162
case Kernel.ParallelCompiler . compile ( [ mixfile ] ) do
163
163
{ :ok , _ , warnings } ->
164
164
{ :ok , Enum . map ( warnings , & Diagnostics . mixfile_diagnostic ( & 1 , :warning ) ) }
@@ -174,39 +174,65 @@ defmodule ElixirLS.LanguageServer.Build do
174
174
# restore warnings
175
175
Code . put_compiler_option ( :no_warn_undefined , old_undefined )
176
176
177
- if status == :ok do
177
+ if mixfile_status == :ok do
178
178
# The project may override our logger config, so we reset it after loading their config
179
179
# store log config
180
180
logger_config = Application . get_all_env ( :logger )
181
181
182
- try do
183
- Mix.Task . run ( "loadconfig" )
184
- after
185
- # reset log config
186
- Application . put_all_env ( logger: logger_config )
182
+ { config_result , config_raw_diagnostics } =
183
+ with_diagnostics ( [ log: true ] , fn ->
184
+ try do
185
+ Mix.Task . run ( "loadconfig" )
186
+ :ok
187
+ catch
188
+ kind , err ->
189
+ { payload , stacktrace } = Exception . blame ( kind , err , __STACKTRACE__ )
190
+ { :error , kind , payload , stacktrace }
191
+ after
192
+ # reset log config
193
+ Application . put_all_env ( logger: logger_config )
194
+
195
+ if Version . match? ( System . version ( ) , ">= 1.15.0" ) do
196
+ # remove all log handlers and restore our
197
+ for handler_id <- :logger . get_handler_ids ( ) ,
198
+ handler_id != Logger.Backends.JsonRpc do
199
+ :ok = :logger . remove_handler ( handler_id )
200
+ end
201
+
202
+ if Logger.Backends.JsonRpc not in :logger . get_handler_ids ( ) do
203
+ :ok =
204
+ :logger . add_handler (
205
+ Logger.Backends.JsonRpc ,
206
+ Logger.Backends.JsonRpc ,
207
+ Logger.Backends.JsonRpc . handler_config ( )
208
+ )
209
+ end
210
+ end
187
211
188
- if Version . match? ( System . version ( ) , ">= 1.15.0" ) do
189
- # remove all log handlers and restore our
190
- for handler_id <- :logger . get_handler_ids ( ) , handler_id != Logger.Backends.JsonRpc do
191
- :ok = :logger . remove_handler ( handler_id )
212
+ # make sure ANSI is disabled
213
+ Application . put_env ( :elixir , :ansi_enabled , false )
192
214
end
215
+ end )
193
216
194
- if Logger.Backends.JsonRpc not in :logger . get_handler_ids ( ) do
195
- :ok =
196
- :logger . add_handler (
197
- Logger.Backends.JsonRpc ,
198
- Logger.Backends.JsonRpc ,
199
- Logger.Backends.JsonRpc . handler_config ( )
200
- )
201
- end
202
- end
217
+ config_diagnostics =
218
+ config_raw_diagnostics
219
+ |> Enum . map ( & Diagnostics . code_diagnostic / 1 )
220
+
221
+ case config_result do
222
+ { :error , kind , err , stacktrace } ->
223
+ config_path = Mix.Project . config ( ) [ :config_path ]
224
+
225
+ { :error ,
226
+ mixfile_diagnostics ++
227
+ config_diagnostics ++
228
+ [ Diagnostics . error_to_diagnostic ( kind , err , stacktrace , config_path ) ] }
203
229
204
- # make sure ANSI is disabled
205
- Application . put_env ( :elixir , :ansi_enabled , false )
230
+ :ok ->
231
+ { :ok , mixfile_diagnostics ++ config_diagnostics }
206
232
end
233
+ else
234
+ { mixfile_status , mixfile_diagnostics }
207
235
end
208
-
209
- { status , diagnostics }
210
236
else
211
237
msg =
212
238
"No mixfile found in project. " <>
@@ -450,4 +476,13 @@ defmodule ElixirLS.LanguageServer.Build do
450
476
end
451
477
end
452
478
end
479
+
480
+ def with_diagnostics ( opts \\ [ ] , fun ) do
481
+ # Code.with_diagnostics is broken on elixir < 1.15.3
482
+ if Version . match? ( System . version ( ) , ">= 1.15.3" ) do
483
+ Code . with_diagnostics ( opts , fun )
484
+ else
485
+ { fun . ( ) , [ ] }
486
+ end
487
+ end
453
488
end
0 commit comments