mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-11 13:59:14 +02:00
codetools: added InsertStatements
git-svn-id: trunk@47837 -
This commit is contained in:
parent
7110836ddc
commit
f4c1725bcd
@ -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';
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user