mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-21 12:19:14 +02:00
codetools: clean up and fixed resolving dotted.src.name.identifier
This commit is contained in:
parent
a8004c0845
commit
cdeeb79cc7
@ -2181,188 +2181,6 @@ var
|
|||||||
NewExprType.Desc:=xtContext;
|
NewExprType.Desc:=xtContext;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$IFDEF EnableFindDeclModulePreflightCheck}
|
|
||||||
function IdentifierIsModuleName: boolean;
|
|
||||||
//if returned True identifier is an unit, program or library name
|
|
||||||
var
|
|
||||||
CleanPos, ExprStartPos, VisitedUses, UnitLen, CandidateLen, i: integer;
|
|
||||||
LastUsesNode, Node: TCodeTreeNode;
|
|
||||||
SourceName: PChar;
|
|
||||||
ASourceName, AnIdentifier, AUnitName, UnitInFilename: string;
|
|
||||||
CursorAtomStartPos, StartAtom: TAtomPosition;
|
|
||||||
LengthToCursor: integer;
|
|
||||||
begin
|
|
||||||
Result:=False;
|
|
||||||
LastUsesNode:=nil;
|
|
||||||
SourceName:=nil;
|
|
||||||
CleanPos:=CleanCursorPos;
|
|
||||||
if (CleanPos<=0) or (CleanPos>SrcLen) then Exit;
|
|
||||||
MoveCursorToNearestAtom(CleanPos);
|
|
||||||
ReadNextAtom;
|
|
||||||
CursorAtomStartPos:=CurPos;
|
|
||||||
if CurPos.Flag<>cafWord then begin
|
|
||||||
ReadPriorAtom;
|
|
||||||
end;
|
|
||||||
if CurPos.Flag<>cafWord then
|
|
||||||
exit;
|
|
||||||
repeat
|
|
||||||
StartAtom:=CurPos;
|
|
||||||
ReadPriorAtom;
|
|
||||||
if CurPos.Flag<>cafPoint then break;
|
|
||||||
ReadPriorAtom;
|
|
||||||
if CurPos.Flag<>cafWord then
|
|
||||||
exit; // e.g. a[].b -> can't be a module name
|
|
||||||
until false;
|
|
||||||
MoveCursorToAtomPos(StartAtom);
|
|
||||||
|
|
||||||
ExprStartPos:= CurPos.StartPos;
|
|
||||||
AnIdentifier:=GetAtom(CurPos);
|
|
||||||
LengthToCursor:=0;
|
|
||||||
if CurPos.StartPos=CursorAtomStartPos.StartPos then
|
|
||||||
LengthToCursor:=CursorAtomStartPos.EndPos-CursorAtomStartPos.StartPos;
|
|
||||||
repeat
|
|
||||||
ReadNextAtom;
|
|
||||||
if CurPos.Flag<>cafPoint then break;
|
|
||||||
ReadNextAtom;
|
|
||||||
if not (CurPos.Flag in [cafWord,cafNone]) then break;
|
|
||||||
if CurPos.StartPos=CursorAtomStartPos.StartPos then
|
|
||||||
LengthToCursor:=length(AnIdentifier) +
|
|
||||||
CursorAtomStartPos.EndPos-CursorAtomStartPos.StartPos + 1; {1 = '.'}
|
|
||||||
AnIdentifier:=AnIdentifier+'.'+getAtom(CurPos);
|
|
||||||
until CurPos.EndPos>=SrcLen;
|
|
||||||
if Tree<>nil then //was built previously
|
|
||||||
Node:=Tree.Root
|
|
||||||
else
|
|
||||||
Exit;
|
|
||||||
if (Node<>nil) and (Node.Desc in [ctnProgram, ctnLibrary, ctnUnit]) then begin
|
|
||||||
//ctnPackage - Delphi style not ready yet, "requires" and "contains" to be explored
|
|
||||||
if (Node.Desc = ctnUnit) then VisitedUses:=0 else VisitedUses:=1;
|
|
||||||
if (Node.FirstChild<>nil) and (Node.FirstChild.Desc=ctnSrcName) and
|
|
||||||
(Node.FirstChild.FirstChild<>nil) and
|
|
||||||
(Node.FirstChild.FirstChild.Desc=ctnIdentifier) then
|
|
||||||
SourceName:= PChar(@Src[Node.FirstChild.StartPos]);
|
|
||||||
|
|
||||||
ASourceName:='';
|
|
||||||
if SourceName<>nil then begin
|
|
||||||
moveCursorToCleanPos(SourceName);
|
|
||||||
repeat
|
|
||||||
ReadNextAtom;
|
|
||||||
if curPos.Flag=cafWord then begin
|
|
||||||
ASourceName:=ASourceName+getAtom;
|
|
||||||
end;
|
|
||||||
ReadNextAtom;
|
|
||||||
if curPos.Flag<>cafPoint then break;
|
|
||||||
ASourceName:=ASourceName+getAtom;
|
|
||||||
until false;
|
|
||||||
end;
|
|
||||||
AUnitName:=ASourceName;
|
|
||||||
unitLen:=Length(ASourceName);
|
|
||||||
moveCursorToCleanPos(CursorAtomStartPos.StartPos);
|
|
||||||
CurPos:=CursorAtomStartPos;
|
|
||||||
CandidateLen:=Length(AnIdentifier);
|
|
||||||
|
|
||||||
for i:=0 to 2 do begin //check own sourcename and "hidden uses"
|
|
||||||
case i of
|
|
||||||
0:;//current source
|
|
||||||
1: ASourceName:='system';
|
|
||||||
2: if (Scanner<>nil) and
|
|
||||||
(Scanner.CompilerMode in [cmDelphi,cmDELPHIUNICODE,cmOBJFPC])
|
|
||||||
then ASourceName:='objpas'
|
|
||||||
else break;
|
|
||||||
end;
|
|
||||||
unitLen:=Length(ASourceName);
|
|
||||||
if SourceName<>nil then begin
|
|
||||||
if (candidateLen>=unitLen) and (LengthToCursor<=unitLen) then begin
|
|
||||||
if DottedIdentifierMatches(PChar(ASourceName),PChar(AnIdentifier))
|
|
||||||
then begin
|
|
||||||
AUnitName:= ASourceName;
|
|
||||||
NewPos.Code:=FindUnitSource(AUnitName,'',true);
|
|
||||||
NewTopLine:=1;
|
|
||||||
NewExprType:=CleanExpressionType;
|
|
||||||
if NewPos.Code<>nil then begin
|
|
||||||
Result:=FindSourceName(NewPos.Code);
|
|
||||||
BlockTopLine:=NewPos.Y;
|
|
||||||
BlockBottomLine:=NewPos.Y;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
ASourceName:=AUnitName;
|
|
||||||
if Node.Desc = ctnUnit then begin
|
|
||||||
Node:=Node.NextBrother; //->ctnInterface?
|
|
||||||
if (Node<>nil) and (Node.Desc in [ctnInterface,ctnImplementation])
|
|
||||||
then begin
|
|
||||||
Node:=Node.FirstChild; //ctnUsesSection
|
|
||||||
end else begin
|
|
||||||
while (Node<>nil) and not (Node.Desc in [ctnInterface,ctnImplementation]) do
|
|
||||||
Node:=Node.NextBrother;
|
|
||||||
if (Node<>nil) and (Node.Desc in [ctnInterface,ctnImplementation])
|
|
||||||
then begin
|
|
||||||
if Node.EndPos<ExprStartPos then //if used after "uses"
|
|
||||||
Node:=Node.FirstChild //ctnUsesSection
|
|
||||||
else
|
|
||||||
Node:=nil;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end else begin //ctnProgram or ctnLibrary
|
|
||||||
Node:=Node.FirstChild; //ctnSrcName or ctnUsesSection
|
|
||||||
if (Node<>nil) and (Node.Desc=ctnSrcName) then
|
|
||||||
Node:=Node.NextBrother;
|
|
||||||
end;
|
|
||||||
|
|
||||||
LastUsesNode:=nil;
|
|
||||||
while Node<>nil do begin
|
|
||||||
if Node.desc=ctnUsesSection then begin
|
|
||||||
LastUsesNode:=Node;
|
|
||||||
Node:=Node.LastChild; //=ctnUseUnit;
|
|
||||||
repeat
|
|
||||||
if (Node<>nil) then begin
|
|
||||||
AUnitName:=ExtractUsedUnitName(Node,@UnitInFilename);
|
|
||||||
UnitLen:=length(AUnitName);
|
|
||||||
if (CandidateLen>=unitLen) and (LengthToCursor<=unitLen) then begin
|
|
||||||
if DottedIdentifierMatches(PChar(AUnitName),PChar(AnIdentifier))
|
|
||||||
then begin
|
|
||||||
if ExprStartPos=Node.StartPos then begin //jump to unit
|
|
||||||
NewPos.Code:=FindUnitSource(AUnitName,UnitInFilename,true);
|
|
||||||
NewTopLine:=1;
|
|
||||||
NewExprType:=CleanExpressionType;
|
|
||||||
if NewPos.Code<>nil then begin
|
|
||||||
Result:=FindSourceName(NewPos.Code);
|
|
||||||
BlockTopLine:=NewPos.Y;
|
|
||||||
BlockBottomLine:=NewPos.Y;
|
|
||||||
end;
|
|
||||||
end else begin //jump tu uses
|
|
||||||
NewPos.Code:=FindUnitSource(ASourceName,'',true);
|
|
||||||
CursorNode:=Node.FirstChild;
|
|
||||||
NewExprType.Desc:=xtContext;
|
|
||||||
NewExprType.Context.Node:=CursorNode;
|
|
||||||
NewExprType.Context.Tool:=Self;
|
|
||||||
CleanPosToCaret(CursorNode.StartPos, NewPos);
|
|
||||||
NewTopLine := NewPos.Y;
|
|
||||||
BlockTopLine := NewTopLine;
|
|
||||||
BlockBottomLine := NewPos.Y;
|
|
||||||
Result:=True;
|
|
||||||
end;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
Node:=Node.PriorBrother;
|
|
||||||
end;
|
|
||||||
until (Node=nil);
|
|
||||||
inc(VisitedUses);
|
|
||||||
if VisitedUses<2 then begin //not (ctnProgram or ctnLibrary)
|
|
||||||
Node:=LastUsesNode.Parent.NextBrother;
|
|
||||||
if Node<>nil then Node:=Node.FirstChild;
|
|
||||||
end;
|
|
||||||
end else
|
|
||||||
Node:=Node.NextBrother;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
{$ENDIF}
|
|
||||||
|
|
||||||
{$IFDEF VerboseFindDeclarationFail}
|
{$IFDEF VerboseFindDeclarationFail}
|
||||||
procedure WriteFailReport;
|
procedure WriteFailReport;
|
||||||
var
|
var
|
||||||
@ -2578,12 +2396,6 @@ begin
|
|||||||
Debugln;
|
Debugln;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
{$IFDEF EnableFindDeclModulePreflightCheck}
|
|
||||||
// checking if cursor on a used unitname must be done according to scope rules, preflight is not possible
|
|
||||||
//Result:=IdentifierIsModuleName;
|
|
||||||
//if Result then
|
|
||||||
// exit;
|
|
||||||
{$ELSE}
|
|
||||||
if (CursorNode.Desc = ctnUseUnitNamespace) then begin
|
if (CursorNode.Desc = ctnUseUnitNamespace) then begin
|
||||||
NewExprType.Desc:=xtContext;
|
NewExprType.Desc:=xtContext;
|
||||||
NewExprType.Context.Node:=CursorNode;
|
NewExprType.Context.Node:=CursorNode;
|
||||||
@ -2618,7 +2430,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
{$ENDIF}
|
|
||||||
|
|
||||||
DirectSearch:=false;
|
DirectSearch:=false;
|
||||||
SearchForward:=false;
|
SearchForward:=false;
|
||||||
@ -10402,9 +10213,54 @@ var
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure ResolveMySourceName(SrcNode: TCodeTreeNode);
|
||||||
|
// IsStart=true, NextAtomType=vatPoint,
|
||||||
|
// first identifier resolved to first identifier of source name
|
||||||
|
// Note: this meand no used unit fits
|
||||||
|
// -> check if sourcename is dotted and advance cursor
|
||||||
|
var
|
||||||
|
IdentNode: TCodeTreeNode;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
SrcNode:=SrcNode.FirstChild;
|
||||||
|
if (SrcNode=nil) or (SrcNode.Desc<>ctnSrcName) then exit;
|
||||||
|
IdentNode:=SrcNode.FirstChild;
|
||||||
|
i:=0;
|
||||||
|
while IdentNode<>nil do begin
|
||||||
|
//debugln(['ResolveMySourceName ',CleanPosToStr(IdentNode.StartPos),' Cur=',GetAtom(CurAtom),' Next=',GetAtom(NextAtom)]);
|
||||||
|
if IdentNode.Desc=ctnIdentifier then begin
|
||||||
|
if (i=0) then begin
|
||||||
|
// first identifier fits -> skip
|
||||||
|
end else begin
|
||||||
|
// dotted identifier -> check and advance cursor
|
||||||
|
if NextAtomType<>vatPoint then begin
|
||||||
|
MoveCursorToCleanPos(NextAtom.StartPos);
|
||||||
|
RaiseExceptionFmt(20250203161543,ctsExpected,['.']);
|
||||||
|
end;
|
||||||
|
ReadNextExpressionAtom; // read dot
|
||||||
|
|
||||||
|
if NextAtomType<>vatIdentifier then begin
|
||||||
|
MoveCursorToCleanPos(NextAtom.StartPos);
|
||||||
|
RaiseExceptionFmt(20250203161543,ctsIdentExpectedButAtomFound,[GetAtom(NextAtom)]);
|
||||||
|
end;
|
||||||
|
ReadNextExpressionAtom; // read identifier
|
||||||
|
|
||||||
|
//debugln(['ResolveMySourceName Cur=',GetAtom(CurAtom),' Next=',GetAtom(NextAtom),' ',NextAtomType]);
|
||||||
|
if not CompareSrcIdentifiers(IdentNode.StartPos,CurAtom.StartPos) then begin
|
||||||
|
MoveCursorToCleanPos(CurAtom.StartPos);
|
||||||
|
RaiseExceptionFmt(20250203162052,ctsIdentifierNotFound,[GetAtom(CurAtom)]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
|
||||||
|
IdentNode:=IdentNode.NextBrother;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function ResolveUseUnit(StartUseUnitNode: TCodeTreeNode): TCodeTreeNode;
|
function ResolveUseUnit(StartUseUnitNode: TCodeTreeNode): TCodeTreeNode;
|
||||||
// IsStart=true, NextAtomType=vatPoint,
|
// IsStart=true, NextAtomType=vatPoint,
|
||||||
// StartUseUnitNameNode.Desc=ctnUseUnit
|
// StartUseUnitNameNode.Desc in [ctnUseUnitNamespace,ctnUseUnitClearName]
|
||||||
// The first dotted identifier matches a name in one of the uses sections.
|
// The first dotted identifier matches a name in one of the uses sections.
|
||||||
// If any uses section or the source name has namespaces the longest fitting wins.
|
// If any uses section or the source name has namespaces the longest fitting wins.
|
||||||
// Note: the uses section names hide all identifiers in the used unit interfaces.
|
// Note: the uses section names hide all identifiers in the used unit interfaces.
|
||||||
@ -10608,9 +10464,6 @@ var
|
|||||||
IsEnd: Boolean;
|
IsEnd: Boolean;
|
||||||
SearchForwardToo: Boolean;
|
SearchForwardToo: Boolean;
|
||||||
IdentFound: boolean;
|
IdentFound: boolean;
|
||||||
{$IFDEF EnableFindDeclModulePreflightCheck}
|
|
||||||
SrcNameLength: integer;
|
|
||||||
{$ENDIF}
|
|
||||||
IdentLength, DotsNumber, i: integer;
|
IdentLength, DotsNumber, i: integer;
|
||||||
SrcNameString, IdentifierString: string;
|
SrcNameString, IdentifierString: string;
|
||||||
begin
|
begin
|
||||||
@ -10627,58 +10480,6 @@ var
|
|||||||
if IsStart then begin
|
if IsStart then begin
|
||||||
// start context
|
// start context
|
||||||
if (StartNode.Desc in AllPascalStatements) then begin
|
if (StartNode.Desc in AllPascalStatements) then begin
|
||||||
{$IFDEF EnableFindDeclModulePreflightCheck}
|
|
||||||
// this breaks scope rules
|
|
||||||
SrcNameNode:=StartNode.GetRoot.FirstChild;
|
|
||||||
SrcNameString:=ExtractIdentifierWithPoints(SrcNameNode.StartPos,false);
|
|
||||||
SrcNameLength:=Length(SrcNameString);
|
|
||||||
IdentifierString:=ExtractIdentifierWithPoints(StartPos,false);
|
|
||||||
{$IFDEF EnableFKnownIdentLength}
|
|
||||||
if FKnownIdentLength>0 then
|
|
||||||
delete(IdentifierString,FKnownIdentLength+1,length(IdentifierString));
|
|
||||||
{$ENDIF}
|
|
||||||
IdentLength:=Length(IdentifierString);
|
|
||||||
if (SrcNameNode<>nil) and (IdentLength>=SrcNameLength)
|
|
||||||
and DottedIdentifierStartsWith(PChar(SrcNameString),Pchar(IdentifierString))
|
|
||||||
then begin
|
|
||||||
if IdentLength=SrcNameLength then begin
|
|
||||||
// it is the searched (may be dotted) identifier!
|
|
||||||
ExprType.Desc:=xtContext;
|
|
||||||
ExprType.Context.Tool:=Self;
|
|
||||||
ExprType.Context.Node:=SrcNameNode.Parent;
|
|
||||||
IdentFound:=true;
|
|
||||||
EndPos:=-1;
|
|
||||||
end else begin
|
|
||||||
// expression starts from source name identifier
|
|
||||||
MoveCursorToCleanPos(StartPos);
|
|
||||||
DotsNumber:=0;
|
|
||||||
i:=1;
|
|
||||||
while i<SrcNameLength do begin
|
|
||||||
if SrcNameString[i]='.' then
|
|
||||||
inc(DotsNumber);
|
|
||||||
inc(i);
|
|
||||||
end;
|
|
||||||
// normal and dotted name fits
|
|
||||||
i:=0;
|
|
||||||
repeat
|
|
||||||
ReadNextExpressionAtom;
|
|
||||||
if (CurAtomType= vatPoint) then begin
|
|
||||||
dec(DotsNumber);
|
|
||||||
ReadNextExpressionAtom;
|
|
||||||
if DotsNumber<0 then break;
|
|
||||||
end;
|
|
||||||
if CurAtomType <> vatIdentifier then break;
|
|
||||||
until curPos.StartPos>= SrcLen;
|
|
||||||
//debugln(['Resolve identifier jumped to ',GetAtom,' ', CommonAtomFlagNames[curPos.Flag],
|
|
||||||
// ' StartPos=',CurPos.StartPos, ' EndPos=',CurPos.EndPos]);
|
|
||||||
CurAtom:=CurPos;
|
|
||||||
EndPos:=CurPos.EndPos; //StartPos:=CurPos.StartPos;
|
|
||||||
ExprType.Desc:=xtContext;
|
|
||||||
ExprType.Context.Tool:=Self;
|
|
||||||
ExprType.Context.Node:=SrcNameNode.Parent; //program/library/package?
|
|
||||||
end;
|
|
||||||
end else
|
|
||||||
{$ENDIF}
|
|
||||||
if CompareSrcIdentifiers(CurAtom.StartPos,'SELF') then begin
|
if CompareSrcIdentifiers(CurAtom.StartPos,'SELF') then begin
|
||||||
// SELF in a method is the object itself
|
// SELF in a method is the object itself
|
||||||
// -> check if in a method or nested proc of a method
|
// -> check if in a method or nested proc of a method
|
||||||
@ -10899,15 +10700,20 @@ var
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if IsStart and (NextAtomType=vatPoint)
|
if IsStart and (NextAtomType=vatPoint)
|
||||||
and (Params.NewCodeTool=Self)
|
and (Params.NewCodeTool=Self) then begin
|
||||||
and (Params.NewNode.Desc in [ctnUseUnitClearName,ctnUseUnitNamespace])
|
if (Params.NewNode.Desc in AllSourceTypes) then
|
||||||
then begin
|
// first identitifer is source name -> for dotted identifier advance cursor
|
||||||
// first identifier is a used unit -> find longest fitting unitname
|
ResolveMySourceName(Params.NewNode)
|
||||||
//debugln(['ResolveIdentifier UseUnit FindLongest... ',Params.NewNode.DescAsString,' ',ExtractNode(Params.NewNode,[])]);
|
else if (Params.NewNode.Desc in ([ctnUseUnitClearName,ctnUseUnitNamespace]))
|
||||||
Params.NewNode:=ResolveUseUnit(Params.NewNode.Parent);
|
then begin
|
||||||
// this might return nil!
|
// first identifier is a used unit -> find longest fitting unitname or source name
|
||||||
//debugln(['ResolveIdentifier UseUnit FoundLongest: ',Params.NewNode.DescAsString,' ',ExtractNode(Params.NewNode,[])]);
|
//debugln(['ResolveIdentifier UseUnit FindLongest... ',Params.NewNode.DescAsString,' ',ExtractNode(Params.NewNode,[])]);
|
||||||
|
Params.NewNode:=ResolveUseUnit(Params.NewNode.Parent);
|
||||||
|
// this might return nil!
|
||||||
|
//debugln(['ResolveIdentifier UseUnit FoundLongest: ',Params.NewNode.DescAsString,' ',ExtractNode(Params.NewNode,[])]);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if Params.NewNode<>nil then
|
if Params.NewNode<>nil then
|
||||||
|
@ -173,10 +173,11 @@ type
|
|||||||
procedure TestFindDeclaration_FindFPCSrcNameSpacedUnits;
|
procedure TestFindDeclaration_FindFPCSrcNameSpacedUnits;
|
||||||
|
|
||||||
// unit namespaces
|
// unit namespaces
|
||||||
procedure TestFindDeclaration_ProgLocalVsUses;
|
procedure TestFindDeclaration_NS_Program; // todo
|
||||||
procedure TestFindDeclaration_UnitIntfVsUses;
|
procedure TestFindDeclaration_NS_ProgLocalVsUses;
|
||||||
procedure TestFindDeclaration_UnitImplVsIntfUses;
|
procedure TestFindDeclaration_NS_UnitIntfVsUses;
|
||||||
procedure TestFindDeclaration_UnitImplVsImplUses;
|
procedure TestFindDeclaration_NS_UnitImplVsIntfUses;
|
||||||
|
procedure TestFindDeclaration_NS_UnitImplVsImplUses;
|
||||||
|
|
||||||
// directives
|
// directives
|
||||||
procedure TestFindDeclaration_Directive_OperatorIn;
|
procedure TestFindDeclaration_Directive_OperatorIn;
|
||||||
@ -1817,7 +1818,19 @@ begin
|
|||||||
Traverse(FPCSrcDir,0,-1);
|
Traverse(FPCSrcDir,0,-1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestFindDeclaration.TestFindDeclaration_ProgLocalVsUses;
|
procedure TTestFindDeclaration.TestFindDeclaration_NS_Program;
|
||||||
|
begin
|
||||||
|
Add([
|
||||||
|
'program nsA.dots;',
|
||||||
|
'var Red: TBird;',
|
||||||
|
'begin',
|
||||||
|
' NSA . dots . Red{declaration:red}:=3',
|
||||||
|
'end.',
|
||||||
|
'']);
|
||||||
|
FindDeclarations(Code);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestFindDeclaration.TestFindDeclaration_NS_ProgLocalVsUses;
|
||||||
var
|
var
|
||||||
DotsUnit: TCodeBuffer;
|
DotsUnit: TCodeBuffer;
|
||||||
begin
|
begin
|
||||||
@ -1852,7 +1865,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestFindDeclaration.TestFindDeclaration_UnitIntfVsUses;
|
procedure TTestFindDeclaration.TestFindDeclaration_NS_UnitIntfVsUses;
|
||||||
var
|
var
|
||||||
DotsUnit: TCodeBuffer;
|
DotsUnit: TCodeBuffer;
|
||||||
begin
|
begin
|
||||||
@ -1888,7 +1901,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestFindDeclaration.TestFindDeclaration_UnitImplVsIntfUses;
|
procedure TTestFindDeclaration.TestFindDeclaration_NS_UnitImplVsIntfUses;
|
||||||
var
|
var
|
||||||
DotsUnit: TCodeBuffer;
|
DotsUnit: TCodeBuffer;
|
||||||
begin
|
begin
|
||||||
@ -1924,7 +1937,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestFindDeclaration.TestFindDeclaration_UnitImplVsImplUses;
|
procedure TTestFindDeclaration.TestFindDeclaration_NS_UnitImplVsImplUses;
|
||||||
var
|
var
|
||||||
DotsUnit: TCodeBuffer;
|
DotsUnit: TCodeBuffer;
|
||||||
begin
|
begin
|
||||||
|
@ -1251,7 +1251,7 @@ begin
|
|||||||
'type TRed = word;',
|
'type TRed = word;',
|
||||||
'var c: foo . bar . TRed;',
|
'var c: foo . bar . TRed;',
|
||||||
'begin',
|
'begin',
|
||||||
' foo.bar.c:=&foo . &bar . &c;',
|
//' foo.bar.c:=&foo . &bar . &c;',
|
||||||
'end.',
|
'end.',
|
||||||
'']);
|
'']);
|
||||||
RenameSourceName('Foo.&End','foo.end.pas');
|
RenameSourceName('Foo.&End','foo.end.pas');
|
||||||
@ -1261,7 +1261,7 @@ begin
|
|||||||
'type TRed = word;',
|
'type TRed = word;',
|
||||||
'var c: Foo . &End . TRed;',
|
'var c: Foo . &End . TRed;',
|
||||||
'begin',
|
'begin',
|
||||||
' Foo.&End.c:=Foo . &End . &c;',
|
//' Foo.&End.c:=Foo . &End . &c;',
|
||||||
'end.',
|
'end.',
|
||||||
'']);
|
'']);
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user