codetools: added InsertStatements

git-svn-id: trunk@47837 -
This commit is contained in:
mattias 2015-02-16 21:52:05 +00:00
parent 7110836ddc
commit f4c1725bcd
5 changed files with 78 additions and 47 deletions

View File

@ -86,7 +86,7 @@ uses
CodeCache, CustomCodeTool, PascalParserTool, MethodJumpTool,
FindDeclarationTool, KeywordFuncLists, CodeToolsStructs, BasicCodeTools,
LinkScanner, SourceChanger, CodeGraph, AVL_Tree, contnrs,
CodeCompletionTemplater;
CodeCompletionTemplater, StdCodeTools;
type
TNewClassPart = (ncpPrivateProcs, ncpPrivateVars,
@ -117,14 +117,6 @@ const
);
type
TInsertStatementPosDescription = class
public
InsertPos: integer;
CodeXYPos: TCodeXYPosition;
FrontGap, AfterGap: TGapTyp;
Description: string;
end;
TCodeCompletionCodeTool = class;
{ TCodeCompletionCodeTool }
@ -6134,6 +6126,11 @@ begin
InsertPosDesc:=TInsertStatementPosDescription.Create;
InsertPosDesc.InsertPos:=BeginNode.StartPos+length('begin');
CleanPosToCaret(InsertPosDesc.InsertPos,InsertPosDesc.CodeXYPos);
InsertPosDesc.Indent:=GetLineIndent(Src,BeginNode.StartPos);
if SourceChangeCache<>nil then
inc(InsertPosDesc.Indent,SourceChangeCache.BeautifyCodeOptions.Indent)
else
inc(InsertPosDesc.Indent,2);
InsertPosDesc.FrontGap:=gtNewLine;
InsertPosDesc.AfterGap:=gtNewLine;
InsertPosDesc.Description:='After BEGIN keyword';

View File

@ -528,18 +528,14 @@ type
SectionCode: TCodeBuffer; SectionX, SectionY: integer;
const NewIdentifier, NewValue: string;
InsertPolicy: TResourcestringInsertPolicy): boolean;
procedure ImproveStringConstantStart(const ACode: string;
var StartPos: integer);
procedure ImproveStringConstantEnd(const ACode: string;
var EndPos: integer);
// expressions
function GetStringConstBounds(Code: TCodeBuffer; X,Y: integer;
var StartCode: TCodeBuffer; var StartX, StartY: integer;
var EndCode: TCodeBuffer; var EndX, EndY: integer;
ResolveComments: boolean): boolean;
function ReplaceCode(Code: TCodeBuffer; StartX, StartY: integer;
EndX, EndY: integer; const NewCode: string): boolean;
procedure ImproveStringConstantStart(const ACode: string; var StartPos: integer);
procedure ImproveStringConstantEnd(const ACode: string; var EndPos: integer);
function ExtractOperand(Code: TCodeBuffer; X,Y: integer;
out Operand: string; WithPostTokens, WithAsOperator,
WithoutTrailingPoints: boolean): boolean;
@ -574,6 +570,8 @@ type
): boolean;
function DeclareVariableAt(Code: TCodeBuffer; X,Y: integer;
const VariableName, NewType, NewUnitName: string): boolean;
// simplifications
function FindRedefinitions(Code: TCodeBuffer;
out TreeOfCodeTreeNodeExt: TAVLTree; WithEnums: boolean): boolean;
function RemoveRedefinitions(Code: TCodeBuffer;
@ -607,12 +605,17 @@ type
out AllRemoved: boolean;
const Attr: TProcHeadAttributes;
out RemovedProcHeads: TStrings): boolean;
function FindUnusedUnits(Code: TCodeBuffer; Units: TStrings): boolean;
// custom class completion
function InitClassCompletion(Code: TCodeBuffer;
const AClassName: string; out CodeTool: TCodeTool): boolean;
// insert/replace
function ReplaceCode(Code: TCodeBuffer; StartX, StartY: integer;
EndX, EndY: integer; const NewCode: string): boolean;
function InsertStatements(InsertPos: TInsertStatementPosDescription;
const Statements: string): boolean;
// extract proc (creates a new procedure from code in selection)
function CheckExtractProc(Code: TCodeBuffer;
const StartPoint, EndPoint: TPoint;
@ -689,6 +692,7 @@ type
function FindUnitSource(Code: TCodeBuffer;
const AnUnitName, AnUnitInFilename: string): TCodeBuffer;
function CreateUsesGraph: TUsesGraph;
function FindUnusedUnits(Code: TCodeBuffer; Units: TStrings): boolean;
// resources
property OnFindDefinePropertyForContext: TOnFindDefinePropertyForContext
@ -3026,6 +3030,21 @@ begin
end;
end;
function TCodeToolManager.InsertStatements(
InsertPos: TInsertStatementPosDescription; const Statements: string): boolean;
begin
Result:=false;
{$IFDEF CTDEBUG}
DebugLn('TCodeToolManager.InsertStatements A ',Code.Filename,' Line=',Y,',Col=',X);
{$ENDIF}
if not InitCurCodeTool(InsertPos.CodeXYPos.Code) then exit;
try
Result:=FCurCodeTool.InsertStatements(InsertPos,Statements,SourceChangeCache);
except
on e: Exception do HandleException(e);
end;
end;
function TCodeToolManager.ExtractOperand(Code: TCodeBuffer; X, Y: integer; out
Operand: string; WithPostTokens, WithAsOperator,
WithoutTrailingPoints: boolean): boolean;

View File

@ -200,9 +200,6 @@ type
procedure BeginParsingAndGetCleanPos(
Range: TLinkScannerRange; CursorPos: TCodeXYPosition;
out CleanCursorPos: integer);
procedure BeginParsingAndGetCleanPosOLD(
OnlyInterfaceNeeded: boolean; CursorPos: TCodeXYPosition;
out CleanCursorPos: integer);
function StringIsKeyWord(const Word: string): boolean;
@ -2008,19 +2005,6 @@ begin
end;
end;
procedure TCustomCodeTool.BeginParsingAndGetCleanPosOLD(
OnlyInterfaceNeeded: boolean; CursorPos: TCodeXYPosition;
out CleanCursorPos: integer);
var
Range: TLinkScannerRange;
begin
if OnlyInterfaceNeeded then
Range:=lsrImplementationStart
else
Range:=lsrEnd;
BeginParsingAndGetCleanPos(Range,CursorPos,CleanCursorPos);
end;
function TCustomCodeTool.IgnoreErrorAfterPositionIsInFrontOfLastErrMessage: boolean;
var
IgnoreErrorAfterCleanPos: integer;
@ -2754,7 +2738,7 @@ procedure TCustomCodeTool.GetCleanPosInfo(CodePosInFront, CleanPos: integer;
ResolveComments: if CleanPos is in a comment, parse again in the comment (not recursive)
SameArea: area around CleanPos, either an atom, comment, directive or space
if CleanPos<CodePosInFront then CleanAtomPosition
if CleanPos>SrcLen then CurPos.StartPos>SrcLen
if CleanPos>SrcLen then SameArea.StartPos>SrcLen
}
var
ANode: TCodeTreeNode;

View File

@ -30,7 +30,8 @@ program initvariable;
uses
Classes, SysUtils, contnrs, CodeCache, CodeToolManager, DefineTemplates,
FileProcs, CodeToolsConfig, CodeToolsStructs, CodeCompletionTool, initvars1;
FileProcs, CodeToolsConfig, CodeToolsStructs, CodeCompletionTool,
StdCodeTools, initvars1;
const
ConfigFilename = 'codetools.config';
@ -87,6 +88,16 @@ begin
writeln(CodeXYPos.Code.Filename,'(',CodeXYPos.Y,',',CodeXYPos.X,'): ',Description);
end;
end;
// insert the first statement at the first position
InsertPosDesc:=TInsertStatementPosDescription(InsertPositions[0]);
if not CodeToolBoss.InsertStatements(InsertPosDesc,Statements[0]) then begin
writeln('CodeToolBoss.InsertStatements failed');
exit;
end;
writeln('New source (not saved to disk):');
writeln(Code.Source);
finally
Statements.Free;
InsertPositions.Free;

View File

@ -57,6 +57,15 @@ uses
CustomCodeTool, CodeToolsStructs, LazFileUtils;
type
TInsertStatementPosDescription = class
public
InsertPos: integer;
Indent: integer;
CodeXYPos: TCodeXYPosition;
FrontGap, AfterGap: TGapTyp;
Description: string;
end;
TUsesSection = (usMain, usImplementation);
TOnFindDefinePropertyForContext = procedure(Sender: TObject;
@ -222,11 +231,10 @@ type
function RemoveIdentifierDefinition(const CursorPos: TCodeXYPosition;
SourceChangeCache: TSourceChangeCache): boolean;
function InsertStatements(const CursorPos: TCodeXYPosition;
Statements: string; FrontGap, AfterGap: TGapTyp;
SourceChangeCache: TSourceChangeCache): boolean;
function InsertStatements(InsertPos: TInsertStatementPosDescription;
Statements: string; SourceChangeCache: TSourceChangeCache): boolean;
function InsertStatements(CleanPos: integer;
Statements: string; FrontGap, AfterGap: TGapTyp;
Statements: string; Indent: integer; FrontGap, AfterGap: TGapTyp;
SourceChangeCache: TSourceChangeCache): boolean;
// blocks (e.g. begin..end)
@ -4966,20 +4974,20 @@ begin
end;
end;
function TStandardCodeTool.InsertStatements(const CursorPos: TCodeXYPosition;
Statements: string; FrontGap, AfterGap: TGapTyp;
function TStandardCodeTool.InsertStatements(
InsertPos: TInsertStatementPosDescription; Statements: string;
SourceChangeCache: TSourceChangeCache): boolean;
var
CleanCursorPos: integer;
begin
BeginParsingAndGetCleanPos(lsrEnd,CursorPos,CleanCursorPos);
Result:=InsertStatements(CleanCursorPos,Statements,FrontGap,AfterGap,
SourceChangeCache);
BeginParsingAndGetCleanPos(lsrEnd,InsertPos.CodeXYPos,CleanCursorPos);
Result:=InsertStatements(CleanCursorPos,Statements,InsertPos.Indent,
InsertPos.FrontGap,InsertPos.AfterGap,SourceChangeCache);
Result:=SourceChangeCache.Apply;
end;
function TStandardCodeTool.InsertStatements(CleanPos: integer;
Statements: string; FrontGap, AfterGap: TGapTyp;
Statements: string; Indent: integer; FrontGap, AfterGap: TGapTyp;
SourceChangeCache: TSourceChangeCache): boolean;
{
ToDo: check for "uses" in Statements and extend uses section
@ -4989,19 +4997,31 @@ function TStandardCodeTool.InsertStatements(CleanPos: integer;
}
var
Node: TCodeTreeNode;
SameArea: TAtomPosition;
BeautifyFlags: TBeautifyCodeFlags;
begin
Node:=FindDeepestNodeAtPos(CleanPos,true);
if not (Node.Desc in AllPascalStatements) then begin
MoveCursorToCleanPos(CleanPos);
RaiseException('invalid position for insertion');
RaiseException('invalid position for insertion of statements');
end;
if Node.Desc=ctnBeginBlock then
Node:=BuildSubTreeAndFindDeepestNodeAtPos(Node,CleanPos,true);
// ToDo: check for CleanPos
GetCleanPosInfo(Node.StartPos,CleanPos,false,SameArea);
if (SameArea.StartPos>SrcLen) or (not IsSpaceChar[Src[SameArea.StartPos]])
then begin
MoveCursorToCleanPos(CleanPos);
RaiseException('invalid position for insertion of statements');
end;
SourceChangeCache.MainScanner:=Scanner;
BeautifyFlags:=[bcfIndentExistingLineBreaks];
if FrontGap in [gtNone,gtSpace] then
include(BeautifyFlags,bcfDoNotIndentFirstLine);
Statements:=SourceChangeCache.BeautifyCodeOptions.BeautifyStatement(
Statements,Indent,BeautifyFlags);
Result:=SourceChangeCache.Replace(FrontGap,AfterGap,CleanPos,CleanPos,Statements);
end;