From 871e67c3a5ae9f1ae3b0d5b3da72b0d58bfff9aa Mon Sep 17 00:00:00 2001 From: mattias Date: Tue, 5 May 2009 09:41:10 +0000 Subject: [PATCH] codetools: complete local var assignments: adding unit to uses section git-svn-id: trunk@19811 - --- components/codetools/codecompletiontool.pas | 52 ++++++++++++++------ components/codetools/finddeclarationtool.pas | 45 +++++++++++++++-- components/codetools/identcompletiontool.pas | 30 ----------- 3 files changed, 77 insertions(+), 50 deletions(-) diff --git a/components/codetools/codecompletiontool.pas b/components/codetools/codecompletiontool.pas index 2313d21f75..886b045766 100644 --- a/components/codetools/codecompletiontool.pas +++ b/components/codetools/codecompletiontool.pas @@ -115,7 +115,8 @@ type TCodeCompletionCodeTool = class; TOnGetNewVariableLocation = function(Tool: TCodeCompletionCodeTool; - const VariableName: string; var VariableType: string; + const VariableName: string; + var VariableType, VariableUnitName: string; IsMethod: boolean; NewLocation: TNewVarLocation ): boolean; @@ -169,14 +170,14 @@ type function CheckLocalVarAssignmentSyntax(CleanCursorPos: integer; out VarNameAtom,AssignmentOperator,TermAtom: TAtomPosition): boolean; function AddLocalVariable(CleanCursorPos: integer; OldTopLine: integer; - VariableName, VariableType: string; - out NewPos: TCodeXYPosition; out NewTopLine: integer; - SourceChangeCache: TSourceChangeCache): boolean; + VariableName, VariableType, VariableTypeUnitName: string; + out NewPos: TCodeXYPosition; out NewTopLine: integer; + SourceChangeCache: TSourceChangeCache): boolean; procedure AdjustCursor(OldCodePos: TCodePosition; OldTopLine: integer; out NewPos: TCodeXYPosition; out NewTopLine: integer); function AddVariable(CursorNode: TCodeTreeNode; CleanCursorPos,OldTopLine: integer; - const VariableName, NewType: string; + const VariableName, NewType, NewUnitName: string; out NewPos: TCodeXYPosition; out NewTopLine: integer; SourceChangeCache: TSourceChangeCache): boolean; procedure AddNeededUnitToMainUsesSection(AnUnitName: PChar); @@ -847,7 +848,7 @@ end; function TCodeCompletionCodeTool.AddLocalVariable( CleanCursorPos: integer; OldTopLine: integer; - VariableName, VariableType: string; + VariableName, VariableType, VariableTypeUnitName: string; out NewPos: TCodeXYPosition; out NewTopLine: integer; SourceChangeCache: TSourceChangeCache): boolean; var @@ -912,7 +913,14 @@ begin InsertTxt,Indent); //DebugLn('TCodeCompletionCodeTool.AddLocalVariable E ',InsertTxt,' '); SourceChangeCache.Replace(gtNewLine,gtNewLine,InsertPos,InsertPos,InsertTxt); - if not SourceChangeCache.Apply then exit; + + if (VariableTypeUnitName<>'') then begin + if not AddUnitToMainUsesSection(VariableTypeUnitName,'',SourceChangeCache) + then + exit; + end else begin + if not SourceChangeCache.Apply then exit; + end; // adjust cursor position AdjustCursor(OldCodePos,OldTopLine,NewPos,NewTopLine); @@ -935,29 +943,30 @@ end; function TCodeCompletionCodeTool.AddVariable(CursorNode: TCodeTreeNode; CleanCursorPos, - OldTopLine: integer; const VariableName, NewType: string; + OldTopLine: integer; const VariableName, NewType, NewUnitName: string; out NewPos: TCodeXYPosition; out NewTopLine: integer; SourceChangeCache: TSourceChangeCache): boolean; var VarLocation: TNewVarLocation; IsMethod: Boolean; VarType: String; + VarTypeUnitName: String; begin // ask what for location of new variable VarLocation:=ncpvLocal; VarType:=NewType; + VarTypeUnitName:=NewUnitName; if Assigned(OnGetNewVariableLocation) then begin IsMethod:=NodeIsInAMethod(CursorNode); - if not OnGetNewVariableLocation(Self,VariableName,VarType, + if not OnGetNewVariableLocation(Self,VariableName,VarType,VarTypeUnitName, IsMethod,VarLocation) then exit; end; // all needed parameters found Result:=true; - // add local variable if not AddLocalVariable(CleanCursorPos, OldTopLine, - VariableName, VarType, + VariableName, VarType, VarTypeUnitName, NewPos, NewTopLine, SourceChangeCache) then RaiseException('CompleteLocalVariableAssignment Internal error: AddLocalVariable'); @@ -1044,6 +1053,8 @@ var VarNameAtom, AssignmentOperator, TermAtom: TAtomPosition; NewType: string; Params: TFindDeclarationParams; + ExprType: TExpressionType; + MissingUnit: String; begin Result:=false; @@ -1085,7 +1096,7 @@ begin ' Term="',copy(Src,TermAtom.StartPos,TermAtom.EndPos-TermAtom.StartPos),'"'); {$ENDIF} // find type of term - NewType:=FindTermTypeAsString(TermAtom,CursorNode,Params); + NewType:=FindTermTypeAsString(TermAtom,CursorNode,Params,ExprType); if NewType='' then RaiseException('CompleteLocalVariableAssignment Internal error: NewType=""'); @@ -1093,9 +1104,14 @@ begin Params.Free; DeactivateGlobalWriteLock; end; - + + MissingUnit:=''; + if (ExprType.Desc=xtContext) + and (ExprType.Context.Tool<>nil) then + MissingUnit:=GetUnitForUsesSection(ExprType.Context.Tool); + Result:=AddVariable(CursorNode,CleanCursorPos,OldTopLine,GetAtom(VarNameAtom), - NewType,NewPos,NewTopLine,SourceChangeCache); + NewType,MissingUnit,NewPos,NewTopLine,SourceChangeCache); end; function TCodeCompletionCodeTool.CompleteLocalVariableByParameter( @@ -1110,6 +1126,7 @@ var TypeNode: TCodeTreeNode; NewType: String; IgnorePos: TCodePosition; + MissingUnitName: String; begin Result:=false; @@ -1170,6 +1187,7 @@ begin ClearIgnoreErrorAfter; end; NewType:=''; + MissingUnitName:=''; if Params.NewNode<>nil then begin DebugLn('TCodeCompletionCodeTool.CompleteLocalVariableAsParameter Proc/PropNode=',Params.NewNode.DescAsString,' ',copy(Params.NewCodeTool.Src,Params.NewNode.StartPos,50)); ParameterNode:=Params.NewCodeTool.FindNthParameterNode(Params.NewNode, @@ -1188,6 +1206,10 @@ begin end; NewType:=copy(Params.NewCodeTool.Src,TypeNode.StartPos, TypeNode.EndPos-TypeNode.StartPos); + + // ToDo: find unit of type declaration + MissingUnitName:=''; //GetUnitForUsesSection(Params.NewCodeTool); + DebugLn('TCodeCompletionCodeTool.CompleteLocalVariableAsParameter NewType=',NewType); if NewType='' then RaiseException('CompleteLocalVariableAsParameter Internal error: NewType=""'); @@ -1205,7 +1227,7 @@ begin end; Result:=AddVariable(CursorNode,CleanCursorPos,OldTopLine,GetAtom(VarNameAtom), - NewType,NewPos,NewTopLine,SourceChangeCache); + NewType,MissingUnitName,NewPos,NewTopLine,SourceChangeCache); end; function TCodeCompletionCodeTool.CompleteMethodByBody( diff --git a/components/codetools/finddeclarationtool.pas b/components/codetools/finddeclarationtool.pas index 10018d78b5..95ebbb4afb 100644 --- a/components/codetools/finddeclarationtool.pas +++ b/components/codetools/finddeclarationtool.pas @@ -636,7 +636,8 @@ type function GetExpressionTypeOfTypeIdentifier( Params: TFindDeclarationParams): TExpressionType; function FindTermTypeAsString(TermAtom: TAtomPosition; - CursorNode: TCodeTreeNode; Params: TFindDeclarationParams): string; + CursorNode: TCodeTreeNode; Params: TFindDeclarationParams; + out ExprType: TExpressionType): string; function FindExprTypeAsString(const ExprType: TExpressionType; TermCleanPos: integer; Params: TFindDeclarationParams): string; protected @@ -742,6 +743,7 @@ type out NamePos, InPos: TAtomPosition): boolean; function FindUnitInAllUsesSections(const UpperUnitName: string; out NamePos, InPos: TAtomPosition): boolean; + function GetUnitForUsesSection(Tool: TFindDeclarationTool): string; function FindUnitSource(const AnUnitName, AnUnitInFilename: string; ExceptionOnNotFound: boolean): TCodeBuffer; @@ -1716,7 +1718,7 @@ function TFindDeclarationTool.FindNameInUsesSection(UsesNode: TCodeTreeNode; begin Result:=UsesNode.FirstChild; while (Result<>nil) - and CompareSrcIdentifier(Result.StartPos,PChar(UnitName)) do + and (not CompareSrcIdentifier(Result.StartPos,PChar(UnitName))) do Result:=Result.NextBrother; end; @@ -1777,6 +1779,39 @@ begin 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; begin Result:=Tree.Root; @@ -8472,12 +8507,12 @@ begin end; function TFindDeclarationTool.FindTermTypeAsString(TermAtom: TAtomPosition; - CursorNode: TCodeTreeNode; Params: TFindDeclarationParams): string; -var - ExprType: TExpressionType; + CursorNode: TCodeTreeNode; Params: TFindDeclarationParams; + out ExprType: TExpressionType): string; begin {$IFDEF CheckNodeTool}CheckNodeTool(CursorNode);{$ENDIF} Result:=''; + ExprType:=CleanExpressionType; Params.ContextNode:=CursorNode; Params.Flags:=[fdfSearchInParentNodes,fdfSearchInAncestors, fdfTopLvlResolving,fdfFunctionResult]; diff --git a/components/codetools/identcompletiontool.pas b/components/codetools/identcompletiontool.pas index d2187d9a77..c3513211a8 100644 --- a/components/codetools/identcompletiontool.pas +++ b/components/codetools/identcompletiontool.pas @@ -203,7 +203,6 @@ type function StartUpAtomBehindIs(const s: string): boolean; function CompletePrefix(const OldPrefix: string): string; procedure ToolTreeChange(Tool: TCustomCodeTool; NodesDeleting: boolean); - function GetUnitForUsesSection(Item: TIdentifierListItem): string; public property Context: TFindContext read FContext write FContext; property ContextFlags: TIdentifierListContextFlags @@ -788,35 +787,6 @@ begin 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 } function TIdentCompletionTool.CollectAllIdentifiers(