Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion src/serverprotocol/PasLS.CodeUtils.pas
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface
SysUtils, Classes, FPJSON,
{ CodeTools }
CodeCache, CodeTree, PascalReaderTool, PascalParserTool, IdentCompletionTool, BasicCodeTools,
CodeToolManager,
CodeToolManager, CodeAtom,
{ LazUtils }
FileUtil,
{ Pasls }
Expand Down Expand Up @@ -68,6 +68,7 @@ TJSONSerializedArray = class (TJSONString)
end;

{ Functions }
function IsIdentifier(CodeBuffer: TCodeBuffer; X, Y: Integer): Boolean;
function GetIdentifierAtPos(Tool: TPascalReaderTool; StartPos: Longint; aSkipAmp: Boolean = true; IncludeDot: Boolean = false; IncludeOps: Boolean = false): String;
function GetIdentifierRangeAtPos(Code: TCodeBuffer; X, Y: Integer): TRange;
function FindIdentifierClass(Identifier: TIdentifierListItem): ShortString;
Expand All @@ -86,6 +87,46 @@ procedure GetProjectUnits(const MainFilename: String; Files: TStrings; PreLoad:

implementation

function IsIdentifier(CodeBuffer: TCodeBuffer; X, Y: Integer): Boolean;
var
IsString, IsComment, isKeyword: Boolean;
CursorPos: TCodeXYPosition;
CodeTool: TCodeTool;
SameArea: TAtomPosition;
CleanPos: integer;
begin
IsString := False;
IsComment := False;
isKeyword := False;

CursorPos.Code := CodeBuffer;
CursorPos.X := X;
CursorPos.Y := Y;
CodeTool:=TCodeTool(CodeToolBoss.FindCodeToolForSource(CodeBuffer));

if CodeTool.CaretToCleanPos(CursorPos, CleanPos) <> 0 then
exit;

CodeTool.BuildTreeAndGetCleanPos(CursorPos, CleanPos);
CodeTool.GetCleanPosInfo(-1, CleanPos, false, SameArea);

if SameArea.Flag = cafNone then
IsComment := (SameArea.StartPos <= CleanPos) and (CleanPos < SameArea.EndPos);

if not IsComment then
begin
CodeTool.MoveCursorToCleanPos(SameArea.StartPos);
CodeTool.ReadNextAtom;

if CodeTool.AtomIsStringConstant then
IsString := True
else if CodeTool.StringIsKeyWord(CodeTool.GetAtom) then
isKeyword := True;
end;

Result := not (IsString or isKeyword or IsComment);
end;

function GetIdentifierRangeAtPos(Code: TCodeBuffer; X, Y: Integer): TRange;
var
Line: String;
Expand Down
24 changes: 17 additions & 7 deletions src/serverprotocol/PasLS.GotoDefinition.pas
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ interface

uses
{ RTL }
Classes,
Classes, sysutils,
{ Code Tools }
CodeToolManager, CodeCache,
CodeToolManager, CodeCache, BasicCodeTools, CodeTree,
{ Protocol }
LSP.Base, LSP.Basic;

Expand All @@ -48,13 +48,15 @@ function TGotoDefinition.Process(var Params: TTextDocumentPositionParams): TLoca
var
Code: TCodeBuffer;
NewCode: TCodeBuffer;
X, Y: Integer;
X, Y, AbsPos: Integer;
NewX, NewY, NewTopLine: integer;

begin with Params do
begin
Code := CodeToolBoss.FindFile(textDocument.localPath);
X := position.character;
Y := position.line;

{
NOTE: Use FindMainDeclaration to skip forward declarations and find
the main/complete declaration. This is the correct behavior for
Expand All @@ -70,11 +72,19 @@ function TGotoDefinition.Process(var Params: TTextDocumentPositionParams): TLoca

FindMainDeclaration returns the main declaration location.
}
if CodeToolBoss.FindMainDeclaration(Code, X + 1, Y + 1, NewCode, NewX, NewY, NewTopLine) then
if IsIdentifier(Code, X + 1, Y + 1) then
begin
Result := TLocation.Create;
Result.uri := PathToURI(NewCode.Filename);
Result.range := GetIdentifierRangeAtPos(NewCode, NewX, NewY - 1);
if CodeToolBoss.FindMainDeclaration(Code, X + 1, Y + 1, NewCode, NewX, NewY, NewTopLine) then
begin
Result := TLocation.Create;
Result.uri := PathToURI(NewCode.Filename);
Result.range := GetIdentifierRangeAtPos(NewCode, NewX, NewY - 1);
end
else
begin
Result := nil;
PublishCodeToolsError(Transport,'');
end;
end
else
begin
Expand Down
Loading