codetools: complete local var assignments: adding unit to uses section

git-svn-id: trunk@19811 -
This commit is contained in:
mattias 2009-05-05 09:41:10 +00:00
parent 620900273e
commit 871e67c3a5
3 changed files with 77 additions and 50 deletions

View File

@ -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(

View File

@ -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];

View File

@ -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(