mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 11:59:20 +02:00
codetools: complete local var assignments: adding unit to uses section
git-svn-id: trunk@19811 -
This commit is contained in:
parent
620900273e
commit
871e67c3a5
@ -115,7 +115,8 @@ type
|
|||||||
TCodeCompletionCodeTool = class;
|
TCodeCompletionCodeTool = class;
|
||||||
|
|
||||||
TOnGetNewVariableLocation = function(Tool: TCodeCompletionCodeTool;
|
TOnGetNewVariableLocation = function(Tool: TCodeCompletionCodeTool;
|
||||||
const VariableName: string; var VariableType: string;
|
const VariableName: string;
|
||||||
|
var VariableType, VariableUnitName: string;
|
||||||
IsMethod: boolean; NewLocation: TNewVarLocation
|
IsMethod: boolean; NewLocation: TNewVarLocation
|
||||||
): boolean;
|
): boolean;
|
||||||
|
|
||||||
@ -169,14 +170,14 @@ type
|
|||||||
function CheckLocalVarAssignmentSyntax(CleanCursorPos: integer;
|
function CheckLocalVarAssignmentSyntax(CleanCursorPos: integer;
|
||||||
out VarNameAtom,AssignmentOperator,TermAtom: TAtomPosition): boolean;
|
out VarNameAtom,AssignmentOperator,TermAtom: TAtomPosition): boolean;
|
||||||
function AddLocalVariable(CleanCursorPos: integer; OldTopLine: integer;
|
function AddLocalVariable(CleanCursorPos: integer; OldTopLine: integer;
|
||||||
VariableName, VariableType: string;
|
VariableName, VariableType, VariableTypeUnitName: string;
|
||||||
out NewPos: TCodeXYPosition; out NewTopLine: integer;
|
out NewPos: TCodeXYPosition; out NewTopLine: integer;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
procedure AdjustCursor(OldCodePos: TCodePosition; OldTopLine: integer;
|
procedure AdjustCursor(OldCodePos: TCodePosition; OldTopLine: integer;
|
||||||
out NewPos: TCodeXYPosition; out NewTopLine: integer);
|
out NewPos: TCodeXYPosition; out NewTopLine: integer);
|
||||||
function AddVariable(CursorNode: TCodeTreeNode;
|
function AddVariable(CursorNode: TCodeTreeNode;
|
||||||
CleanCursorPos,OldTopLine: integer;
|
CleanCursorPos,OldTopLine: integer;
|
||||||
const VariableName, NewType: string;
|
const VariableName, NewType, NewUnitName: string;
|
||||||
out NewPos: TCodeXYPosition; out NewTopLine: integer;
|
out NewPos: TCodeXYPosition; out NewTopLine: integer;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
procedure AddNeededUnitToMainUsesSection(AnUnitName: PChar);
|
procedure AddNeededUnitToMainUsesSection(AnUnitName: PChar);
|
||||||
@ -847,7 +848,7 @@ end;
|
|||||||
|
|
||||||
function TCodeCompletionCodeTool.AddLocalVariable(
|
function TCodeCompletionCodeTool.AddLocalVariable(
|
||||||
CleanCursorPos: integer; OldTopLine: integer;
|
CleanCursorPos: integer; OldTopLine: integer;
|
||||||
VariableName, VariableType: string;
|
VariableName, VariableType, VariableTypeUnitName: string;
|
||||||
out NewPos: TCodeXYPosition;
|
out NewPos: TCodeXYPosition;
|
||||||
out NewTopLine: integer; SourceChangeCache: TSourceChangeCache): boolean;
|
out NewTopLine: integer; SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
var
|
var
|
||||||
@ -912,7 +913,14 @@ begin
|
|||||||
InsertTxt,Indent);
|
InsertTxt,Indent);
|
||||||
//DebugLn('TCodeCompletionCodeTool.AddLocalVariable E ',InsertTxt,' ');
|
//DebugLn('TCodeCompletionCodeTool.AddLocalVariable E ',InsertTxt,' ');
|
||||||
SourceChangeCache.Replace(gtNewLine,gtNewLine,InsertPos,InsertPos,InsertTxt);
|
SourceChangeCache.Replace(gtNewLine,gtNewLine,InsertPos,InsertPos,InsertTxt);
|
||||||
|
|
||||||
|
if (VariableTypeUnitName<>'') then begin
|
||||||
|
if not AddUnitToMainUsesSection(VariableTypeUnitName,'',SourceChangeCache)
|
||||||
|
then
|
||||||
|
exit;
|
||||||
|
end else begin
|
||||||
if not SourceChangeCache.Apply then exit;
|
if not SourceChangeCache.Apply then exit;
|
||||||
|
end;
|
||||||
|
|
||||||
// adjust cursor position
|
// adjust cursor position
|
||||||
AdjustCursor(OldCodePos,OldTopLine,NewPos,NewTopLine);
|
AdjustCursor(OldCodePos,OldTopLine,NewPos,NewTopLine);
|
||||||
@ -935,29 +943,30 @@ end;
|
|||||||
|
|
||||||
function TCodeCompletionCodeTool.AddVariable(CursorNode: TCodeTreeNode;
|
function TCodeCompletionCodeTool.AddVariable(CursorNode: TCodeTreeNode;
|
||||||
CleanCursorPos,
|
CleanCursorPos,
|
||||||
OldTopLine: integer; const VariableName, NewType: string;
|
OldTopLine: integer; const VariableName, NewType, NewUnitName: string;
|
||||||
out NewPos: TCodeXYPosition;
|
out NewPos: TCodeXYPosition;
|
||||||
out NewTopLine: integer; SourceChangeCache: TSourceChangeCache): boolean;
|
out NewTopLine: integer; SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
var
|
var
|
||||||
VarLocation: TNewVarLocation;
|
VarLocation: TNewVarLocation;
|
||||||
IsMethod: Boolean;
|
IsMethod: Boolean;
|
||||||
VarType: String;
|
VarType: String;
|
||||||
|
VarTypeUnitName: String;
|
||||||
begin
|
begin
|
||||||
// ask what for location of new variable
|
// ask what for location of new variable
|
||||||
VarLocation:=ncpvLocal;
|
VarLocation:=ncpvLocal;
|
||||||
VarType:=NewType;
|
VarType:=NewType;
|
||||||
|
VarTypeUnitName:=NewUnitName;
|
||||||
if Assigned(OnGetNewVariableLocation) then begin
|
if Assigned(OnGetNewVariableLocation) then begin
|
||||||
IsMethod:=NodeIsInAMethod(CursorNode);
|
IsMethod:=NodeIsInAMethod(CursorNode);
|
||||||
if not OnGetNewVariableLocation(Self,VariableName,VarType,
|
if not OnGetNewVariableLocation(Self,VariableName,VarType,VarTypeUnitName,
|
||||||
IsMethod,VarLocation) then exit;
|
IsMethod,VarLocation) then exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// all needed parameters found
|
// all needed parameters found
|
||||||
Result:=true;
|
Result:=true;
|
||||||
|
|
||||||
// add local variable
|
// add local variable
|
||||||
if not AddLocalVariable(CleanCursorPos, OldTopLine,
|
if not AddLocalVariable(CleanCursorPos, OldTopLine,
|
||||||
VariableName, VarType,
|
VariableName, VarType, VarTypeUnitName,
|
||||||
NewPos, NewTopLine, SourceChangeCache)
|
NewPos, NewTopLine, SourceChangeCache)
|
||||||
then
|
then
|
||||||
RaiseException('CompleteLocalVariableAssignment Internal error: AddLocalVariable');
|
RaiseException('CompleteLocalVariableAssignment Internal error: AddLocalVariable');
|
||||||
@ -1044,6 +1053,8 @@ var
|
|||||||
VarNameAtom, AssignmentOperator, TermAtom: TAtomPosition;
|
VarNameAtom, AssignmentOperator, TermAtom: TAtomPosition;
|
||||||
NewType: string;
|
NewType: string;
|
||||||
Params: TFindDeclarationParams;
|
Params: TFindDeclarationParams;
|
||||||
|
ExprType: TExpressionType;
|
||||||
|
MissingUnit: String;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
|
|
||||||
@ -1085,7 +1096,7 @@ begin
|
|||||||
' Term="',copy(Src,TermAtom.StartPos,TermAtom.EndPos-TermAtom.StartPos),'"');
|
' Term="',copy(Src,TermAtom.StartPos,TermAtom.EndPos-TermAtom.StartPos),'"');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
// find type of term
|
// find type of term
|
||||||
NewType:=FindTermTypeAsString(TermAtom,CursorNode,Params);
|
NewType:=FindTermTypeAsString(TermAtom,CursorNode,Params,ExprType);
|
||||||
if NewType='' then
|
if NewType='' then
|
||||||
RaiseException('CompleteLocalVariableAssignment Internal error: NewType=""');
|
RaiseException('CompleteLocalVariableAssignment Internal error: NewType=""');
|
||||||
|
|
||||||
@ -1094,8 +1105,13 @@ begin
|
|||||||
DeactivateGlobalWriteLock;
|
DeactivateGlobalWriteLock;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
MissingUnit:='';
|
||||||
|
if (ExprType.Desc=xtContext)
|
||||||
|
and (ExprType.Context.Tool<>nil) then
|
||||||
|
MissingUnit:=GetUnitForUsesSection(ExprType.Context.Tool);
|
||||||
|
|
||||||
Result:=AddVariable(CursorNode,CleanCursorPos,OldTopLine,GetAtom(VarNameAtom),
|
Result:=AddVariable(CursorNode,CleanCursorPos,OldTopLine,GetAtom(VarNameAtom),
|
||||||
NewType,NewPos,NewTopLine,SourceChangeCache);
|
NewType,MissingUnit,NewPos,NewTopLine,SourceChangeCache);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCodeCompletionCodeTool.CompleteLocalVariableByParameter(
|
function TCodeCompletionCodeTool.CompleteLocalVariableByParameter(
|
||||||
@ -1110,6 +1126,7 @@ var
|
|||||||
TypeNode: TCodeTreeNode;
|
TypeNode: TCodeTreeNode;
|
||||||
NewType: String;
|
NewType: String;
|
||||||
IgnorePos: TCodePosition;
|
IgnorePos: TCodePosition;
|
||||||
|
MissingUnitName: String;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
|
|
||||||
@ -1170,6 +1187,7 @@ begin
|
|||||||
ClearIgnoreErrorAfter;
|
ClearIgnoreErrorAfter;
|
||||||
end;
|
end;
|
||||||
NewType:='';
|
NewType:='';
|
||||||
|
MissingUnitName:='';
|
||||||
if Params.NewNode<>nil then begin
|
if Params.NewNode<>nil then begin
|
||||||
DebugLn('TCodeCompletionCodeTool.CompleteLocalVariableAsParameter Proc/PropNode=',Params.NewNode.DescAsString,' ',copy(Params.NewCodeTool.Src,Params.NewNode.StartPos,50));
|
DebugLn('TCodeCompletionCodeTool.CompleteLocalVariableAsParameter Proc/PropNode=',Params.NewNode.DescAsString,' ',copy(Params.NewCodeTool.Src,Params.NewNode.StartPos,50));
|
||||||
ParameterNode:=Params.NewCodeTool.FindNthParameterNode(Params.NewNode,
|
ParameterNode:=Params.NewCodeTool.FindNthParameterNode(Params.NewNode,
|
||||||
@ -1188,6 +1206,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
NewType:=copy(Params.NewCodeTool.Src,TypeNode.StartPos,
|
NewType:=copy(Params.NewCodeTool.Src,TypeNode.StartPos,
|
||||||
TypeNode.EndPos-TypeNode.StartPos);
|
TypeNode.EndPos-TypeNode.StartPos);
|
||||||
|
|
||||||
|
// ToDo: find unit of type declaration
|
||||||
|
MissingUnitName:=''; //GetUnitForUsesSection(Params.NewCodeTool);
|
||||||
|
|
||||||
DebugLn('TCodeCompletionCodeTool.CompleteLocalVariableAsParameter NewType=',NewType);
|
DebugLn('TCodeCompletionCodeTool.CompleteLocalVariableAsParameter NewType=',NewType);
|
||||||
if NewType='' then
|
if NewType='' then
|
||||||
RaiseException('CompleteLocalVariableAsParameter Internal error: NewType=""');
|
RaiseException('CompleteLocalVariableAsParameter Internal error: NewType=""');
|
||||||
@ -1205,7 +1227,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
Result:=AddVariable(CursorNode,CleanCursorPos,OldTopLine,GetAtom(VarNameAtom),
|
Result:=AddVariable(CursorNode,CleanCursorPos,OldTopLine,GetAtom(VarNameAtom),
|
||||||
NewType,NewPos,NewTopLine,SourceChangeCache);
|
NewType,MissingUnitName,NewPos,NewTopLine,SourceChangeCache);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCodeCompletionCodeTool.CompleteMethodByBody(
|
function TCodeCompletionCodeTool.CompleteMethodByBody(
|
||||||
|
@ -636,7 +636,8 @@ type
|
|||||||
function GetExpressionTypeOfTypeIdentifier(
|
function GetExpressionTypeOfTypeIdentifier(
|
||||||
Params: TFindDeclarationParams): TExpressionType;
|
Params: TFindDeclarationParams): TExpressionType;
|
||||||
function FindTermTypeAsString(TermAtom: TAtomPosition;
|
function FindTermTypeAsString(TermAtom: TAtomPosition;
|
||||||
CursorNode: TCodeTreeNode; Params: TFindDeclarationParams): string;
|
CursorNode: TCodeTreeNode; Params: TFindDeclarationParams;
|
||||||
|
out ExprType: TExpressionType): string;
|
||||||
function FindExprTypeAsString(const ExprType: TExpressionType;
|
function FindExprTypeAsString(const ExprType: TExpressionType;
|
||||||
TermCleanPos: integer; Params: TFindDeclarationParams): string;
|
TermCleanPos: integer; Params: TFindDeclarationParams): string;
|
||||||
protected
|
protected
|
||||||
@ -742,6 +743,7 @@ type
|
|||||||
out NamePos, InPos: TAtomPosition): boolean;
|
out NamePos, InPos: TAtomPosition): boolean;
|
||||||
function FindUnitInAllUsesSections(const UpperUnitName: string;
|
function FindUnitInAllUsesSections(const UpperUnitName: string;
|
||||||
out NamePos, InPos: TAtomPosition): boolean;
|
out NamePos, InPos: TAtomPosition): boolean;
|
||||||
|
function GetUnitForUsesSection(Tool: TFindDeclarationTool): string;
|
||||||
|
|
||||||
function FindUnitSource(const AnUnitName,
|
function FindUnitSource(const AnUnitName,
|
||||||
AnUnitInFilename: string; ExceptionOnNotFound: boolean): TCodeBuffer;
|
AnUnitInFilename: string; ExceptionOnNotFound: boolean): TCodeBuffer;
|
||||||
@ -1716,7 +1718,7 @@ function TFindDeclarationTool.FindNameInUsesSection(UsesNode: TCodeTreeNode;
|
|||||||
begin
|
begin
|
||||||
Result:=UsesNode.FirstChild;
|
Result:=UsesNode.FirstChild;
|
||||||
while (Result<>nil)
|
while (Result<>nil)
|
||||||
and CompareSrcIdentifier(Result.StartPos,PChar(UnitName)) do
|
and (not CompareSrcIdentifier(Result.StartPos,PChar(UnitName))) do
|
||||||
Result:=Result.NextBrother;
|
Result:=Result.NextBrother;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1777,6 +1779,39 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFindDeclarationTool.GetUnitForUsesSection(Tool: TFindDeclarationTool
|
||||||
|
): string;
|
||||||
|
var
|
||||||
|
UsesNode: TCodeTreeNode;
|
||||||
|
Alternative: String;
|
||||||
|
begin
|
||||||
|
Result:='';
|
||||||
|
if (Tool=nil) or (Tool.MainFilename='') or (Tool=Self) then
|
||||||
|
exit;
|
||||||
|
Result:=ExtractFileNameOnly(Tool.MainFilename);
|
||||||
|
// check if already there
|
||||||
|
UsesNode:=FindMainUsesSection;
|
||||||
|
if (UsesNode<>nil) and (FindNameInUsesSection(UsesNode,Result)<>nil)
|
||||||
|
then begin
|
||||||
|
DebugLn(['TFindDeclarationTool.GetUnitForUsesSection in main']);
|
||||||
|
Result:='';
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
UsesNode:=FindImplementationUsesSection;
|
||||||
|
if (UsesNode<>nil) and (FindNameInUsesSection(UsesNode,Result)<>nil)
|
||||||
|
then begin
|
||||||
|
DebugLn(['TFindDeclarationTool.GetUnitForUsesSection in implementation']);
|
||||||
|
Result:='';
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
// beautify
|
||||||
|
if Result=lowercase(Result) then begin
|
||||||
|
Alternative:=Tool.GetSourceName(false);
|
||||||
|
if Alternative<>'' then
|
||||||
|
Result:=Alternative;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TFindDeclarationTool.FindInitializationSection: TCodeTreeNode;
|
function TFindDeclarationTool.FindInitializationSection: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
Result:=Tree.Root;
|
Result:=Tree.Root;
|
||||||
@ -8472,12 +8507,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TFindDeclarationTool.FindTermTypeAsString(TermAtom: TAtomPosition;
|
function TFindDeclarationTool.FindTermTypeAsString(TermAtom: TAtomPosition;
|
||||||
CursorNode: TCodeTreeNode; Params: TFindDeclarationParams): string;
|
CursorNode: TCodeTreeNode; Params: TFindDeclarationParams;
|
||||||
var
|
out ExprType: TExpressionType): string;
|
||||||
ExprType: TExpressionType;
|
|
||||||
begin
|
begin
|
||||||
{$IFDEF CheckNodeTool}CheckNodeTool(CursorNode);{$ENDIF}
|
{$IFDEF CheckNodeTool}CheckNodeTool(CursorNode);{$ENDIF}
|
||||||
Result:='';
|
Result:='';
|
||||||
|
ExprType:=CleanExpressionType;
|
||||||
Params.ContextNode:=CursorNode;
|
Params.ContextNode:=CursorNode;
|
||||||
Params.Flags:=[fdfSearchInParentNodes,fdfSearchInAncestors,
|
Params.Flags:=[fdfSearchInParentNodes,fdfSearchInAncestors,
|
||||||
fdfTopLvlResolving,fdfFunctionResult];
|
fdfTopLvlResolving,fdfFunctionResult];
|
||||||
|
@ -203,7 +203,6 @@ type
|
|||||||
function StartUpAtomBehindIs(const s: string): boolean;
|
function StartUpAtomBehindIs(const s: string): boolean;
|
||||||
function CompletePrefix(const OldPrefix: string): string;
|
function CompletePrefix(const OldPrefix: string): string;
|
||||||
procedure ToolTreeChange(Tool: TCustomCodeTool; NodesDeleting: boolean);
|
procedure ToolTreeChange(Tool: TCustomCodeTool; NodesDeleting: boolean);
|
||||||
function GetUnitForUsesSection(Item: TIdentifierListItem): string;
|
|
||||||
public
|
public
|
||||||
property Context: TFindContext read FContext write FContext;
|
property Context: TFindContext read FContext write FContext;
|
||||||
property ContextFlags: TIdentifierListContextFlags
|
property ContextFlags: TIdentifierListContextFlags
|
||||||
@ -788,35 +787,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TIdentifierList.GetUnitForUsesSection(Item: TIdentifierListItem): string;
|
|
||||||
var
|
|
||||||
Alternative: String;
|
|
||||||
UsesNode: TCodeTreeNode;
|
|
||||||
begin
|
|
||||||
Result:='';
|
|
||||||
if (Item.Tool=nil) or (Item.Tool=StartContext.Tool) then
|
|
||||||
exit;
|
|
||||||
Result:=ExtractFileNameOnly(Item.Tool.MainFilename);
|
|
||||||
UsesNode:=Item.Tool.FindMainUsesSection;
|
|
||||||
if (UsesNode<>nil) and (Item.Tool.FindNameInUsesSection(UsesNode,Result)<>nil)
|
|
||||||
then begin
|
|
||||||
Result:='';
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
UsesNode:=Item.Tool.FindImplementationUsesSection;
|
|
||||||
if (UsesNode<>nil) and (Item.Tool.FindNameInUsesSection(UsesNode,Result)<>nil)
|
|
||||||
then begin
|
|
||||||
Result:='';
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if Result=lowercase(Result) then begin
|
|
||||||
Alternative:=Item.Tool.GetSourceName(false);
|
|
||||||
if Alternative<>'' then
|
|
||||||
Result:=Alternative;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TIdentCompletionTool }
|
{ TIdentCompletionTool }
|
||||||
|
|
||||||
function TIdentCompletionTool.CollectAllIdentifiers(
|
function TIdentCompletionTool.CollectAllIdentifiers(
|
||||||
|
Loading…
Reference in New Issue
Block a user