diff --git a/src/serverprotocol/PasLS.General.pas b/src/serverprotocol/PasLS.General.pas index 606f1d5..daa3dd8 100644 --- a/src/serverprotocol/PasLS.General.pas +++ b/src/serverprotocol/PasLS.General.pas @@ -252,13 +252,19 @@ procedure TInitialize.ShowConfigStatus(Params: TInitializeParams; CodeToolsOptio I: Integer; FPCOptions: TStringArray; begin - if Params.clientInfo.version.HasValue then + // clientInfo is optional in the LSP spec and TClientInfo.version is + // not auto-created, so both must be checked before use + if (Params.clientInfo <> nil) and (Params.clientInfo.version <> nil) + and Params.clientInfo.version.HasValue then clientInfoVersion := ' ' + Params.clientInfo.version.Value else clientInfoVersion := ''; DoLog(kStatusPrefix+'Server: ' + {$INCLUDE %DATE%}); - DoLog(kStatusPrefix+'Client: ' + Params.clientInfo.name + clientInfoVersion); + if Params.clientInfo <> nil then + DoLog(kStatusPrefix+'Client: ' + Params.clientInfo.name + clientInfoVersion) + else + DoLog(kStatusPrefix+'Client: [unspecified]'); DoLog(kStatusPrefix+'FPCPath: ' + CodeToolsOptions.FPCPath); DoLog(kStatusPrefix+'FPCSrcDir: ' + CodeToolsOptions.FPCSrcDir); diff --git a/src/serverprotocol/PasLS.Parser.pas b/src/serverprotocol/PasLS.Parser.pas index 9a51365..bbb8e8b 100644 --- a/src/serverprotocol/PasLS.Parser.pas +++ b/src/serverprotocol/PasLS.Parser.pas @@ -125,7 +125,15 @@ procedure TSourceParser.DoError(Sender: TObject; else aCode:=-1; With FParser.CurSourcePos do - FOnError(Self,aContext.Error.Message,FileName,aCode, Row,Column); + begin + // scanner errors (e.g. include file not found) fire before the parser + // advanced, CurSourcePos is still empty (Line=0, Column=0, FileName='') - + // fall back to the buffer filename so the diagnostic keeps a valid URI + if FileName='' then + FOnError(Self,aContext.Error.Message,FCode.FileName,aCode, Row,Column) + else + FOnError(Self,aContext.Error.Message,FileName,aCode, Row,Column); + end; end; end; {$ENDIF} @@ -274,15 +282,18 @@ function TSourceParser.ParseSource: TPasModule; begin FreeAndNil(Result); if Assigned(FOnError) then - With FParser.CurSourcePos do - begin - aCode:=-1; - {$IFDEF MULTIERROR} - if E is EParserError then - aCode:=EParserError(E).ErrNo; - {$ENDIF} - FOnError(Self,E.Message,FileName,aCode,Row,Column); - end; + begin + aCode:=-1; + {$IFDEF MULTIERROR} + if E is EParserError then + aCode:=EParserError(E).ErrNo; + {$ENDIF} + // note: no "with FParser.CurSourcePos do" here - its FileName field is + // empty for scanner errors (e.g. include file not found) and would + // shadow the local Filename, producing diagnostics with a broken URI + FOnError(Self,E.Message,Filename,aCode, + FParser.CurSourcePos.Row,FParser.CurSourcePos.Column); + end; end; end; finally