diff --git a/src/serverprotocol/PasLS.GotoDefinition.pas b/src/serverprotocol/PasLS.GotoDefinition.pas index 7e6aaf9..4bf423f 100644 --- a/src/serverprotocol/PasLS.GotoDefinition.pas +++ b/src/serverprotocol/PasLS.GotoDefinition.pas @@ -25,11 +25,11 @@ interface uses { RTL } - Classes, + Classes, sysutils, { Code Tools } - CodeToolManager, CodeCache, + CodeToolManager, CodeCache, BasicCodeTools, CodeTree, CodeAtom, { Protocol } - LSP.Base, LSP.Basic; + LSP.Base , LSP.Basic; type @@ -48,13 +48,57 @@ function TGotoDefinition.Process(var Params: TTextDocumentPositionParams): TLoca var Code: TCodeBuffer; NewCode: TCodeBuffer; - X, Y: Integer; + X, Y, AbsPos: Integer; NewX, NewY, NewTopLine: integer; + + IsString, IsComment, isKeyword: Boolean; + + function IsIdentifier(CodeBuffer: TCodeBuffer; CaretX, CaretY: 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 := CaretX; + CursorPos.Y := CaretY; + CodeTool:=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; + 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 @@ -70,11 +114,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