MG: enhanced code caching, fixed CursorToCleanPos and beautify statement

git-svn-id: trunk@522 -
This commit is contained in:
lazarus 2001-12-13 23:09:58 +00:00
parent 29511ac4bb
commit 8c514a5ded
10 changed files with 230 additions and 122 deletions

View File

@ -60,13 +60,15 @@ type
procedure SetFilename(const Value: string);
procedure SetScanner(const Value: TLinkScanner);
procedure SetIsDeleted(const NewValue: boolean);
procedure MakeFileDateValid;
public
property Scanner: TLinkScanner read FScanner write SetScanner;
property LastIncludedByFile: string
read FLastIncludedByFile write FLastIncludedByFile;
property Filename: string read FFilename write SetFilename;
function LoadFromFile(const AFilename: string): boolean; override;
function Reload: boolean;
function Reload: boolean; // = LoadFromFile(Filename)
function Revert: boolean; // ignore changes and reload source
function SaveToFile(const AFilename: string): boolean; override;
function Save: boolean;
property FileDateValid: boolean read FFileDateValid;
@ -74,6 +76,7 @@ type
function FileDateOnDisk: longint;
function FileNeedsUpdate: boolean;
function FileOnDiskNeedsUpdate: boolean;
function FileOnDiskHasChanged: boolean;
property OnSetScanner: TNotifyEvent read FOnSetScanner write FOnSetScanner;
property OnSetFilename: TNotifyEvent read FOnSetFilename write FOnSetFilename;
property IsVirtual: boolean read FIsVirtual;
@ -225,10 +228,10 @@ end;
function TCodeCache.LoadFile(const AFilename: string): TCodeBuffer;
// search file in cache
// WARING: this will not check, if file on disk is newer
begin
Result:=FindFile(AFilename);
if Result=nil then begin
// load new buffer
Result:=TCodeBuffer.Create;
Result.Filename:=AFilename;
if (not FileExists(AFilename)) or (not Result.LoadFromFile(AFilename)) then
@ -243,6 +246,7 @@ begin
LastIncludedByFile:=Self.LastIncludedByFile(AFilename);
end;
end else if Result.IsDeleted then begin
// file in cache, but marked as deleted -> load from disk
if (not FileExists(AFilename)) or (not Result.LoadFromFile(AFilename)) then
begin
Result:=nil;
@ -382,12 +386,8 @@ begin
end;
function TCodeCache.OnScannerCheckFileOnDisk(Code: pointer): boolean;
var Buf: TCodeBuffer;
begin
Buf:=TCodeBuffer(Code);
Result:=(not Buf.FileNeedsUpdate) and Buf.FileOnDiskNeedsUpdate;
if Result then
Result:=Buf.LoadFromFile(Buf.Filename);
Result:=TCodeBuffer(Code).Reload;
end;
procedure TCodeCache.OnScannerIncludeCode(ParentCode, IncludeCode: pointer);
@ -589,20 +589,16 @@ begin
end;
if not IsVirtual then begin
if CompareFilenames(AFilename,Filename)=0 then begin
//writeln('****** [TCodeBuffer.LoadFromFile] ',Filename,' ',FFileDateValid,' ',FFileDate,',',FileAge(Filename),',',FFileChangeStep,',',ChangeStep);
if (not FFileDateValid) or (FFileChangeStep<>ChangeStep)
or (FFileDate<>FileAge(Filename)) then begin
Result:=inherited LoadFromFile(AFilename)
//writeln('****** [TCodeBuffer.LoadFromFile] ',Filename,' FileDateValid=',FileDateValid,' ',FFileDate,',',FileAge(Filename),',',FFileChangeStep,',',ChangeStep,', NeedsUpdate=',FileNeedsUpdate);
if FileNeedsUpdate then begin
Result:=inherited LoadFromFile(AFilename);
if Result then MakeFileDateValid;
end else
Result:=true;
if FIsDeleted then FIsDeleted:=not Result;
if Result then begin
FFileChangeStep:=ChangeStep;
FFileDateValid:=true;
FFileDate:=FileAge(Filename);
end;
end else begin
Result:=inherited LoadFromFile(AFilename)
Result:=inherited LoadFromFile(AFilename);
if Result then MakeFileDateValid;
end;
end else
Result:=false;
@ -614,11 +610,7 @@ begin
//writeln('TCodeBuffer.SaveToFile ',Filename,' -> ',AFilename,' ',Result);
if CompareFilenames(AFilename,Filename)=0 then begin
if FIsDeleted then FIsDeleted:=not Result;
if Result then begin
FFileChangeStep:=ChangeStep;
FFileDateValid:=true;
FFileDate:=FileAge(Filename);
end;
if Result then MakeFileDateValid;
end;
end;
@ -627,6 +619,16 @@ begin
Result:=LoadFromFile(Filename);
end;
function TCodeBuffer.Revert: boolean;
// ignore changes and reload source
begin
if not IsVirtual then begin
Result:=inherited LoadFromFile(Filename);
if Result then MakeFileDateValid;
end else
Result:=false;
end;
function TCodeBuffer.Save: boolean;
begin
if not IsVirtual then
@ -671,23 +673,41 @@ begin
end;
end;
procedure TCodeBuffer.MakeFileDateValid;
begin
FFileChangeStep:=ChangeStep;
FFileDateValid:=true;
FFileDate:=FileAge(Filename);
end;
function TCodeBuffer.FileDateOnDisk: longint;
begin
Result:=FileAge(Filename);
end;
function TCodeBuffer.FileNeedsUpdate: boolean;
// file needs update, if file is not modified and file on disk is changed
begin
if FileDateValid then
Result:=(FileDateOnDisk>FileDate)
Result:=(not Modified) and (FFileChangeStep=ChangeStep)
and (FileDateOnDisk>FileDate)
else
Result:=true;
end;
function TCodeBuffer.FileOnDiskNeedsUpdate: boolean;
// file on disk needs update, if file is modified
begin
if FileDateValid then
Result:=(FFileChangeStep<>ChangeStep) or (FFileDate<>FileDateOnDisk)
Result:=Modified or (FFileChangeStep<>ChangeStep)
else
Result:=false;
end;
function TCodeBuffer.FileOnDiskHasChanged: boolean;
begin
if FileDateValid then
Result:=(FileDateOnDisk<>FileDate)
else
Result:=false;
end;

View File

@ -218,13 +218,13 @@ var Parts: array[TPropPart] of TAtomPosition;
function ReadSimpleSpec(SpecWord, SpecParam: TPropPart): boolean;
begin
if Parts[SpecWord].StartPos>=1 then begin
Result:=false;
exit;
end;
if Parts[SpecWord].StartPos>=1 then
RaiseException('property specifier already defined: '+GetAtom);
Parts[SpecWord]:=CurPos;
ReadNextAtom;
Result:=AtomIsWord;
if not Result then
RaiseException('expected identifier but '+GetAtom+' found');
if WordIsPropertySpecifier.DoItUpperCase(UpperSrc,CurPos.StartPos,
CurPos.EndPos-CurPos.StartPos) then exit;
Parts[SpecParam]:=CurPos;
@ -250,12 +250,12 @@ writeln('[TCodeCompletionCodeTool.CompleteProperty] Checking Property ',GetAtom)
// read parameter list '[ ... ]'
Parts[ppParamList].StartPos:=CurPos.StartPos;
InitExtraction;
if not ReadParamList(false,true,[phpInUpperCase,phpWithoutBrackets])
if not ReadParamList(true,true,[phpInUpperCase,phpWithoutBrackets])
then begin
{$IFDEF CTDEBUG}
writeln('[TCodeCompletionCodeTool.CompleteProperty] error parsing param list');
{$ENDIF}
exit;
RaiseException('error in paramlist');
end;
CleanParamList:=GetExtraction;
Parts[ppParamList].EndPos:=CurPos.EndPos;
@ -273,22 +273,26 @@ writeln('[TCodeCompletionCodeTool.CompleteProperty] no type : found -> ignore pr
if (CurPos.StartPos>PropNode.EndPos)
or UpAtomIs('END') or AtomIsChar(';') or (not AtomIsIdentifier(false))
or AtomIsKeyWord then begin
// no type name found -> ignore this property
{$IFDEF CTDEBUG}
writeln('[TCodeCompletionCodeTool.CompleteProperty] error: no type name found');
{$ENDIF}
Result:=true;
exit;
end;
Parts[ppType]:=CurPos;
// read specifiers
ReadNextAtom;
if UpAtomIs('INDEX') then begin
if Parts[ppIndexWord].StartPos>=1 then exit;
if Parts[ppIndexWord].StartPos>=1 then
RaiseException('index specifier redefined');
Parts[ppIndexWord]:=CurPos;
ReadNextAtom;
if WordIsPropertySpecifier.DoItUpperCase(UpperSrc,CurPos.StartPos,
CurPos.EndPos-CurPos.StartPos) then exit;
CurPos.EndPos-CurPos.StartPos) then
RaiseException('index parameter expected, but '+GetAtom+' found');
Parts[ppIndex].StartPos:=CurPos.StartPos;
if not ReadConstant(false,false,[]) then exit;
if not ReadConstant(true,false,[]) then exit;
Parts[ppIndex].EndPos:=LastAtoms.GetValueAt(0).EndPos;
end;
if UpAtomIs('READ') and not ReadSimpleSpec(ppReadWord,ppRead) then exit;
@ -300,24 +304,28 @@ writeln('[TCodeCompletionCodeTool.CompleteProperty] error: no type name found');
if not ReadSimpleSpec(ppStoredWord,ppStored) then
exit;
end else if UpAtomIs('DEFAULT') then begin
if Parts[ppDefaultWord].StartPos>=1 then exit;
if Parts[ppDefaultWord].StartPos>=1 then
RaiseException('default specifier redefined');
Parts[ppDefaultWord]:=CurPos;
ReadNextAtom;
if WordIsPropertySpecifier.DoItUpperCase(UpperSrc,CurPos.StartPos,
CurPos.EndPos-CurPos.StartPos) then exit;
CurPos.EndPos-CurPos.StartPos) then
RaiseException('default parameter expected, but '+GetAtom+' found');
Parts[ppDefault].StartPos:=CurPos.StartPos;
if not ReadConstant(false,false,[]) then exit;
if not ReadConstant(true,false,[]) then exit;
Parts[ppDefault].EndPos:=LastAtoms.GetValueAt(0).EndPos;
end else if UpAtomIs('IMPLEMENTS') then begin
if not ReadSimpleSpec(ppImplementsWord,ppImplements) then exit;
end else if UpAtomIs('NODEFAULT') then begin
if Parts[ppNoDefaultWord].StartPos>=1 then exit;
if Parts[ppNoDefaultWord].StartPos>=1 then
RaiseException('nodefault specifier defined twice');
Parts[ppNoDefaultWord]:=CurPos;
ReadNextAtom;
end else
exit;
RaiseException('; expected, but '+GetAtom+' found');
end;
if (CurPos.StartPos>PropNode.EndPos) then exit;
if (CurPos.StartPos>PropNode.EndPos) then
RaiseException('Reparsing error (Complete Property)');
PropType:=copy(Src,Parts[ppType].StartPos,
Parts[ppType].EndPos-Parts[ppType].StartPos);
// check read specifier
@ -370,14 +378,14 @@ writeln('[TCodeCompletionCodeTool.CompleteProperty] CleanAccessFunc ',CleanAcces
MoveCursorToCleanPos(Parts[ppParamList].StartPos);
ReadNextAtom;
InitExtraction;
if not ReadParamList(false,true,[phpWithParameterNames,
if not ReadParamList(true,true,[phpWithParameterNames,
phpWithoutBrackets,phpWithVarModifiers,
phpWithComments])
then begin
{$IFDEF CTDEBUG}
writeln('[TCodeCompletionCodeTool.CompleteProperty] Error reading param list');
{$ENDIF}
exit;
RaiseException('error in parameter list');
end;
ParamList:=GetExtraction;
if (Parts[ppIndexWord].StartPos<1) then begin
@ -483,11 +491,11 @@ writeln('[TCodeCompletionCodeTool.CompleteProperty] write specifier needed');
MoveCursorToCleanPos(Parts[ppParamList].StartPos);
ReadNextAtom;
InitExtraction;
if not ReadParamList(false,true,[phpWithParameterNames,
if not ReadParamList(true,true,[phpWithParameterNames,
phpWithoutBrackets,phpWithVarModifiers,
phpWithComments])
then
exit;
RaiseException('error in param list');
ParamList:=GetExtraction;
if (Parts[ppIndexWord].StartPos<1) then begin
// param list, no index
@ -706,7 +714,9 @@ var
ProcCode:=ANodeExt.ExtTxt1;
ProcCode:=ASourceChangeCache.BeautifyCodeOptions.AddClassNameToProc(
ProcCode,TheClassName);
{$IFDEF CTDEBUG}
writeln('>>> InsertProcBody ',TheClassName,' "',ProcCode,'"');
{$ENDIF}
ProcCode:=ASourceChangeCache.BeautifyCodeOptions.BeautifyProc(
ProcCode,Indent,true);
ASourceChangeCache.Replace(gtEmptyLine,gtEmptyLine,InsertPos,InsertPos,
@ -729,6 +739,7 @@ begin
{$IFDEF CTDEBUG}
writeln('TCodeCompletionCodeTool.CreateMissingProcBodies Gather existing method bodies ... ');
{$ENDIF}
Result:=false;
// gather existing class proc bodies
TypeSectionNode:=ClassNode.Parent;
if (TypeSectionNode<>nil) and (TypeSectionNode.Parent<>nil)
@ -791,17 +802,20 @@ writeln('TCodeCompletionCodeTool.CreateMissingProcBodies Gather existing method
// class is in interface section
// -> insert at the end of the implementation section
ImplementationNode:=FindImplementationNode;
if ImplementationNode=nil then exit;
if ImplementationNode=nil then
RaiseException('implementation node not found');
Indent:=GetLineIndent(Src,ImplementationNode.StartPos);
InsertPos:=ImplementationNode.EndPos;
end else begin
// class is not in interface section
// -> insert at the end of the type section
ANode:=ClassNode.Parent; // type definition
if ANode=nil then exit;
if ANode=nil then
RaiseException('class node without parent node');
if ANode.Parent.Desc=ctnTypeSection then
ANode:=ANode.Parent; // type section
if ANode=nil then exit;
if ANode=nil then
RaiseException('type section of class section not found');
Indent:=GetLineIndent(Src,ANode.StartPos);
InsertPos:=ANode.EndPos;
end;
@ -919,21 +933,24 @@ var CleanCursorPos, Dummy, Indent, insertPos: integer;
ANodeExt: TCodeTreeNodeExtension;
begin
Result:=false;
if (SourceChangeCache=nil) then exit;
if (SourceChangeCache=nil) then
RaiseException('need a SourceChangeCache');
// in a class or in a forward proc?
BuildTree(false);
if not EndOfSourceFound then exit;
if not EndOfSourceFound then
RaiseException('End of Source not found');
ASourceChangeCache:=SourceChangeCache;
SourceChangeCache.MainScanner:=Scanner;
// find the CursorPos in cleaned source
Dummy:=CaretToCleanPos(CursorPos, CleanCursorPos);
if (Dummy<>0) and (Dummy<>-1) then exit;
if (Dummy<>0) and (Dummy<>-1) then
RaiseException('cursor pos outside of code');
// find CodeTreeNode at cursor
CursorNode:=FindDeepestNodeAtPos(CleanCursorPos);
if CursorNode=nil then
exit;
RaiseException('no valid node found at cursor');
{$IFDEF CTDEBUG}
writeln('TCodeCompletionCodeTool.CompleteCode A ',NodeDescriptionAsString(CursorNode.Desc));
writeln('TCodeCompletionCodeTool.CompleteCode A CleanCursorPos=',CleanCursorPos,' NodeDesc=',NodeDescriptionAsString(CursorNode.Desc));
{$ENDIF}
ImplementationNode:=FindImplementationNode;
if ImplementationNode=nil then ImplementationNode:=Tree.Root;
@ -957,7 +974,8 @@ writeln('TCodeCompletionCodeTool.CompleteCode C ',CleanCursorPos,', |',copy(Src,
StartNode:=ClassNode.FirstChild;
while (StartNode<>nil) and (StartNode.FirstChild=nil) do
StartNode:=StartNode.NextBrother;
if StartNode=nil then exit;
if StartNode=nil then
RaiseException('error parsing class');
StartNode:=StartNode.FirstChild;
JumpToProc:='';
try
@ -973,7 +991,8 @@ writeln('TCodeCompletionCodeTool.CompleteCode Complete Properties ... ');
while ANode<>nil do begin
if ANode.Desc=ctnProperty then begin
// check if property is complete
if not CompleteProperty(ANode) then exit;
if not CompleteProperty(ANode) then
RaiseException('unable to complete property');
end;
ANode:=ANode.NextBrother;
end;
@ -984,19 +1003,22 @@ writeln('TCodeCompletionCodeTool.CompleteCode Complete Properties ... ');
writeln('TCodeCompletionCodeTool.CompleteCode Insert new variables and methods ... ');
{$ENDIF}
// insert all new variables and procs definitions
if not InsertAllNewClassParts then exit;
if not InsertAllNewClassParts then
RaiseException('error during inserting new class parts');
{$IFDEF CTDEBUG}
writeln('TCodeCompletionCodeTool.CompleteCode Insert new method bodies ... ');
{$ENDIF}
// insert all missing proc bodies
if not CreateMissingProcBodies then exit;
if not CreateMissingProcBodies then
RaiseException('error during creation of new proc bodies');
{$IFDEF CTDEBUG}
writeln('TCodeCompletionCodeTool.CompleteCode Apply ... ');
{$ENDIF}
// apply the changes and jump to first new proc body
if not SourceChangeCache.Apply then exit;
if not SourceChangeCache.Apply then
RaiseException('unable to apply changes');
if JumpToProc<>'' then begin
// there was a new proc body
@ -1004,25 +1026,31 @@ writeln('TCodeCompletionCodeTool.CompleteCode Apply ... ');
// reparse code
BuildTree(false);
if not EndOfSourceFound then exit;
if not EndOfSourceFound then
RaiseException('End of source not found');
// find the CursorPos in cleaned source
Dummy:=CaretToCleanPos(CursorPos, CleanCursorPos);
if (Dummy<>0) and (Dummy<>-1) then exit;
if (Dummy<>0) and (Dummy<>-1) then
RaiseException('cursor pos outside of code');
// find CodeTreeNode at cursor
CursorNode:=FindDeepestNodeAtPos(CleanCursorPos);
if CursorNode=nil then exit;
if CursorNode=nil then
RaiseException('no valid node found at cursor');
ClassNode:=CursorNode;
while (ClassNode<>nil) and (ClassNode.Desc<>ctnClass) do
ClassNode:=ClassNode.Parent;
if ClassNode=nil then exit;
if ClassNode=nil then
RaiseException('oops, I loosed your class');
ANode:=ClassNode.Parent;
if ANode=nil then exit;
if ANode=nil then
RaiseException('class without parent node');
if (ANode.Parent<>nil) and (ANode.Parent.Desc=ctnTypeSection) then
ANode:=ANode.Parent;
ProcNode:=FindProcNode(ANode,JumpToProc,
[phpInUpperCase,phpIgnoreForwards]);
if ProcNode=nil then exit;
if ProcNode=nil then
RaiseException('new proc body not found');
Result:=FindJumpPointInProcNode(ProcNode,NewPos,NewTopLine);
exit;
end else begin
@ -1046,12 +1074,18 @@ writeln('TCodeCompletionCodeTool.CompleteCode Apply ... ');
end;
end else begin
{$IFDEF CTDEBUG}
writeln('TCodeCompletionCodeTool.CompleteCode not in-a-class ... ');
{$ENDIF}
// then test if forward proc
ProcNode:=CursorNode;
if ProcNode.Desc=ctnProcedureHead then ProcNode:=ProcNode.Parent;
if (ProcNode.Desc=ctnProcedure)
and (ProcNode.SubDesc=ctnsForwardDeclaration) then begin
// Node is forward Proc
{$IFDEF CTDEBUG}
writeln('TCodeCompletionCodeTool.CompleteCode in a forward procedure ... ');
{$ENDIF}
// check if proc already exists
ProcCode:=ExtractProcHead(ProcNode,[phpInUpperCase]);
@ -1059,6 +1093,9 @@ writeln('TCodeCompletionCodeTool.CompleteCode Apply ... ');
[phpInUpperCase])<>nil
then exit;
{$IFDEF CTDEBUG}
writeln('TCodeCompletionCodeTool.CompleteCode Body not found -> create it ... ');
{$ENDIF}
// -> create proc body at end of implementation
Indent:=GetLineIndent(Src,ImplementationNode.StartPos);
@ -1068,7 +1105,8 @@ writeln('TCodeCompletionCodeTool.CompleteCode Apply ... ');
else begin
// insert in front of main program begin..end.
StartNode:=ImplementationNode.LastChild;
if (StartNode=nil) or (StartNode.Desc<>ctnBeginBlock) then exit;
if (StartNode=nil) or (StartNode.Desc<>ctnBeginBlock) then
RaiseException('main Begin..End block not found');
InsertPos:=FindLineEndOrCodeInFrontOfPosition(Src,StartNode.StartPos,
Scanner.NestedComments);
end;
@ -1076,16 +1114,23 @@ writeln('TCodeCompletionCodeTool.CompleteCode Apply ... ');
// build nice proc
ProcCode:=ExtractProcHead(ProcNode,[phpWithStart,phpWithVarModifiers,
phpWithParameterNames,phpWithResultType,phpWithComments]);
if ProcCode='' then exit;
if ProcCode='' then
RaiseException('unable to reparse proc node');
ProcCode:=SourceChangeCache.BeautifyCodeOptions.BeautifyProc(ProcCode,
Indent,true);
if not SourceChangeCache.Replace(gtEmptyLine,gtEmptyLine,
InsertPos,InsertPos,ProcCode) then exit;
if not SourceChangeCache.Apply then exit;
InsertPos,InsertPos,ProcCode) then
RaiseException('unable to insert new proc body');
if not SourceChangeCache.Apply then
RaiseException('unable to apply changes');
// reparse code and find jump point into new proc
Result:=FindJumpPoint(CursorPos,NewPos,NewTopLine);
exit;
end else begin
{$IFDEF CTDEBUG}
writeln('TCodeCompletionCodeTool.CompleteCode nothing to complete ... ');
{$ENDIF}
end;
end;
end;

View File

@ -97,7 +97,8 @@ type
property SourceExtensions: string
read FSourceExtensions write FSourceExtensions;
function FindFile(const ExpandedFilename: string): TCodeBuffer;
function LoadFile(const ExpandedFilename: string): TCodeBuffer;
function LoadFile(const ExpandedFilename: string;
UpdateFromDisk, Revert: boolean): TCodeBuffer;
function CreateFile(const AFilename: string): TCodeBuffer;
function SaveBufferAs(OldBuffer: TCodeBuffer;const ExpandedFilename: string;
var NewBuffer: TCodeBuffer): boolean;
@ -299,9 +300,19 @@ begin
Result:=SourceCache.FindFile(ExpandedFilename);
end;
function TCodeToolManager.LoadFile(const ExpandedFilename: string): TCodeBuffer;
function TCodeToolManager.LoadFile(const ExpandedFilename: string;
UpdateFromDisk, Revert: boolean): TCodeBuffer;
begin
{$IFDEF CTDEBUG}
writeln('>>>>>>>>>>>>>>> [TCodeToolManager.LoadFile] ',ExpandedFilename,' Update=',UpdateFromDisk,' Revert=',Revert);
{$ENDIF}
Result:=SourceCache.LoadFile(ExpandedFilename);
if Result<>nil then begin
if Revert then
Result.Revert
else if UpdateFromDisk then
Result.Reload;
end;
end;
function TCodeToolManager.CreateFile(const AFilename: string): TCodeBuffer;

View File

@ -877,11 +877,14 @@ end;
function TCustomCodeTool.CaretToCleanPos(Caret: TCodeXYPosition;
var CleanPos: integer): integer;
begin
//writeln('TCustomCodeTool.CaretToCleanPos A ',Caret.Code.Filename,' ',Caret.Code.SourceLength);
Caret.Code.LineColToPosition(Caret.Y,Caret.X,CleanPos);
//writeln('TCustomCodeTool.CaretToCleanPos B ',CleanPos,',',Caret.Y,',',Caret.X);
if (CleanPos>=1) then
Result:=Scanner.CursorToCleanPos(CleanPos,Caret.Code,CleanPos)
else
Result:=-2; // x,y beyond source
//writeln('TCustomCodeTool.CaretToCleanPos C CleanPos=',CleanPos,' Result=',Result);
end;
function TCustomCodeTool.CleanPosToCaret(CleanPos: integer;

View File

@ -46,6 +46,7 @@ uses
type
TFindDeclarationTool = class(TPascalParserTool)
public
//function FindDeclaration(CursorPos: TCodeXYPosition; var NewPos: TCodeXYPosition; var NewTopLine: integer): boolean;
end;

View File

@ -1446,31 +1446,32 @@ var i, j: integer;
begin
i:=0;
while i<LinkCount do begin
//writeln('[TLinkScanner.CursorToCleanPos] A ACursorPos=',ACursorPos,', Code=',Links[i].Code=ACode,', Links[i].SrcPos=',Links[i].SrcPos,', Links[i].CleanedPos=',Links[i].CleanedPos);
if (Links[i].Code=ACode) and (Links[i].SrcPos<=ACursorPos) then begin
ACleanPos:=ACursorPos-Links[i].SrcPos+Links[i].CleanedPos;
j:=i+1;
while (j<LinkCount) and (Links[j].Code<>ACode) do inc(j);
if (j<LinkCount) then begin
// there is a link after in the same code
if ACleanPos<Links[j].CleanedPos then begin
Result:=0; exit; // valid position
end else begin
// search next ...
//writeln('[TLinkScanner.CursorToCleanPos] B ACleanPos=',ACleanPos);
if i+1<LinkCount then begin
//writeln('[TLinkScanner.CursorToCleanPos] C Links[i+1].CleanedPos=',Links[i+1].CleanedPos);
if ACleanPos<Links[i+1].CleanedPos then begin
Result:=0; // valid position
exit;
end;
j:=i+1;
while (j<LinkCount) and (Links[j].Code<>ACode) do inc(j);
//writeln('[TLinkScanner.CursorToCleanPos] D j=',j);
if (j<LinkCount) and (Links[j].SrcPos>ACursorPos) then begin
Result:=-1; // CursorPos was skipped, CleanPos is between two links
exit;
end;
// search next
i:=j-1;
end else begin
// last link in Cursor Code
if i+1<LinkCount then begin
if ACleanPos<Links[i+1].CleanedPos then
Result:=0 // valid position
else
Result:=1; // cursor beyond scanned code
end else begin
// in last link
if ACleanPos<=length(FCleanedSrc) then
Result:=0 // valid position
else
Result:=1; // cursor beyond scanned code
end;
// in last link
//writeln('[TLinkScanner.CursorToCleanPos] E length(FCleanedSrc)=',length(FCleanedSrc));
if ACleanPos<=length(FCleanedSrc) then
Result:=0 // valid position
else
Result:=1; // cursor beyond scanned code
exit;
end;
end;

View File

@ -601,7 +601,7 @@ begin
KeyWordPolicy:=wpLowerCase;
IdentifierPolicy:=wpNone;
DoNotSplitLineBefore:=[atColon,atComma,atSemicolon,atPoint];
DoNotSplitLineAfter:=[atColon,atAt,atPoint];
DoNotSplitLineAfter:=[atColon,atAt,atPoint,atKeyWord];
DoInsertSpaceBefore:=[];
DoInsertSpaceAfter:=[atColon,atComma,atSemicolon];
PropertyReadIdentPrefix:='Get';
@ -766,7 +766,8 @@ begin
end;
end;
end;
end;
end else
CurAtomType:=atNone;
AtomEnd:=CurPos;
end;
@ -808,17 +809,25 @@ begin
CurLineLen:=length(Result);
LastAtomType:=atNone;
while (CurPos<=SrcLen) do begin
ReadNextAtom;
CurAtom:=copy(Src,AtomStart,AtomEnd-AtomStart);
if ((CurAtomType in DoInsertSpaceBefore) and (not (LastAtomType=atSpace)))
or ((CurAtomType<>atSpace) and (LastAtomType in DoInsertSpaceAfter)) then
repeat
ReadNextAtom;
CurAtom:=copy(Src,AtomStart,AtomEnd-AtomStart);
if CurAtom=' ' then
AddAtom(Result,' ')
else
break;
until false;
if ((Result='') or (Result[length(Result)]<>' '))
and ((CurAtomType in DoInsertSpaceBefore)
or (LastAtomType in DoInsertSpaceAfter)) then
AddAtom(Result,' ');
if (not (CurAtomType in DoNotSplitLineBefore))
and (not (LastAtomType in DoNotSplitLineAfter)) then
LastSplitPos:=length(Result)+1;
//writeln(' CurPos=',CurPos,' CurAtom="',CurAtom,
//'" CurAtomType=',AtomTypeNames[CurAtomType],' LastAtomType=',AtomTypeNames[LastAtomType],
//' ',LastAtomType in DoInsertSpaceAfter);
{writeln('SPLIT LINE CurPos=',CurPos,' CurAtom="',CurAtom,
'" CurAtomType=',AtomTypeNames[CurAtomType],' LastAtomType=',AtomTypeNames[LastAtomType],
' ',LastAtomType in DoInsertSpaceAfter,' LastSplitPos=',LastSplitPos,
' ..."',copy(Result,length(Result)-10,10),'"'); }
AddAtom(Result,CurAtom);
LastAtomType:=CurAtomType;
end;

View File

@ -359,7 +359,7 @@ end;
procedure TSourceLog.SetSource(const NewSrc: string);
begin
//writeln('TSourceLog.SetSource ',length(NewSrc));
//writeln('TSourceLog.SetSource A ',length(NewSrc),' LineCount=',fLineCount,' SrcLen=',fSrcLen);
if NewSrc<>FSource then begin
Clear;
FSource:=NewSrc;
@ -382,11 +382,11 @@ begin
+Txt
+copy(FSource,Pos,length(FSource)-Pos+1);
FSrcLen:=length(FSource);
FLineCount:=-1;
for i:=0 to FMarkers.Count-1 do begin
if (not Markers[i].Deleted) then
NewSrcLogEntry.AdjustPosition(Markers[i].NewPosition);
end;
FLineCount:=-1;
FModified:=true;
IncreaseChangeStep;
end;
@ -402,6 +402,7 @@ begin
NotifyHooks(NewSrcLogEntry);
System.Delete(FSource,Pos,Len);
FSrcLen:=length(FSource);
FLineCount:=-1;
for i:=0 to FMarkers.Count-1 do begin
if (Markers[i].Deleted=false) then begin
if (Markers[i].NewPosition<=Pos) and (Markers[i].NewPosition<Pos+Len) then
@ -411,7 +412,6 @@ begin
end;
end;
end;
FLineCount:=-1;
FModified:=true;
IncreaseChangeStep;
end;
@ -438,6 +438,7 @@ begin
+Txt
+copy(FSource,Pos+Len,length(FSource)-Pos-Len+1);
FSrcLen:=length(FSource);
FLineCount:=-1;
for i:=0 to FMarkers.Count-1 do begin
if (Markers[i].Deleted=false) then begin
if (Markers[i].NewPosition<=Pos) and (Markers[i].NewPosition<Pos+Len) then
@ -448,7 +449,6 @@ begin
end;
end;
end;
FLineCount:=-1;
FModified:=true;
IncreaseChangeStep;
end;
@ -474,11 +474,11 @@ begin
+copy(FSource,MoveTo,length(FSource)-MoveTo+1);
end;
FSrcLen:=length(FSource);
FLineCount:=-1;
for i:=0 to FMarkers.Count-1 do begin
if (Markers[i].Deleted=false) then
NewSrcLogEntry.AdjustPosition(Markers[i].NewPosition);
end;
FLineCount:=-1;
FModified:=true;
IncreaseChangeStep;
end;
@ -527,6 +527,7 @@ end;
procedure TSourceLog.BuildLineRanges;
var p,line:integer;
begin
//writeln('[TSourceLog.BuildLineRanges] A Self=',HexStr(Cardinal(Self),8),',LineCount=',FLineCount,' Len=',SourceLength);
if FLineCount>=0 then exit;
if FLineRanges<>nil then begin
FreeMem(FLineRanges);
@ -572,6 +573,7 @@ begin
end;
end;
end;
//writeln('[TSourceLog.BuildLineRanges] END ',FLineCount);
end;
procedure TSourceLog.LineColToPosition(Line, Column: integer;
@ -666,6 +668,7 @@ function TSourceLog.SaveToFile(const Filename: string): boolean;
var
fs: TFileStream;
begin
//writeln('TSourceLog.SaveToFile Self=',HexStr(Cardinal(Self),8));
Result:=true;
try
fs:=TFileStream.Create(Filename, fmCreate);
@ -721,6 +724,7 @@ begin
for y:=0 to sl.Count-1 do inc(fSrcLen,length(sl[y]));
fSource:='';
SetLength(fSource,fSrcLen);
fLineCount:=-1;
p:=1;
for y:=0 to sl.Count-1 do begin
s:=sl[y];
@ -768,6 +772,7 @@ begin
SetLength(fSource,fSrcLen);
s.Read(fSource[1],fSrcLen);
end;
fLineCount:=-1;
DecreaseHookLock;
end;

View File

@ -344,7 +344,7 @@ type
function DoSaveCodeBufferToFile(ABuffer: TCodeBuffer;
const AFilename: string; IsPartOfProject:boolean): TModalResult;
function DoLoadCodeBuffer(var ACodeBuffer: TCodeBuffer;
const AFilename: string): TModalResult;
const AFilename: string; UpdateFromDisk, Revert: boolean): TModalResult;
function DoBackupFile(const Filename:string;
IsPartOfProject:boolean): TModalResult;
procedure UpdateCaption;
@ -2357,11 +2357,13 @@ CodeToolBoss.SourceCache.WriteAllFileNames;
{$IFDEF IDE_DEBUG}
writeln('TMainIDE.DoSaveEditorUnit B2 ',ResourceCode<>nil);
{$ENDIF}
if ResourceCode<>nil then
LFMCode:=
CodeToolBoss.LoadFile(ChangeFileExt(ResourceCode.Filename,'.lfm'))
else
LFMCode:=nil;
LFMCode:=nil;
if ResourceCode<>nil then begin
Result:=DoLoadCodeBuffer(LFMCode,
ChangeFileExt(ResourceCode.Filename,'.lfm'),false,false);
if Result<>mrOk then exit;
Result:=mrCancel;
end;
end else
ResourceCode:=nil;
@ -2720,7 +2722,7 @@ CheckHeap(IntToStr(GetMem_Cnt));
Result:=mrOk;
exit;
end;
Result:=DoLoadCodeBuffer(NewBuf,AFileName);
Result:=DoLoadCodeBuffer(NewBuf,AFileName,true,true);
if Result<>mrOk then exit;
NewUnitInfo.Source:=NewBuf;
if (Ext='.pp') or (Ext='.pas') then
@ -2732,7 +2734,7 @@ CheckHeap(IntToStr(GetMem_Cnt));
Result:=DoOpenProjectFile(AFilename);
exit;
end;
Result:=DoLoadCodeBuffer(PreReadBuf,AFileName);
Result:=DoLoadCodeBuffer(PreReadBuf,AFileName,true,true);
if Result<>mrOk then exit;
Result:=mrCancel;
// check if unit is a program
@ -2818,17 +2820,21 @@ writeln('[TMainIDE.DoOpenEditorFile] C');
// this is a unit -> try to find the lfm file
LFMFilename:=ChangeFileExt(NewUnitInfo.Filename,'.lfm');
NewBuf:=nil;
if FileExists(LFMFilename) then
NewBuf:=CodeToolBoss.LoadFile(LFMFilename)
else begin
if FileExists(LFMFilename) then begin
Result:=DoLoadCodeBuffer(NewBuf,LFMFilename,true,false);
if Result<>mrOk then exit;
Result:=mrCancel;
end else begin
i:=-1;
NewBuf:=CodeToolBoss.FindNextResourceFile(NewUnitInfo.Source,i);
if NewBuf<>nil then begin
LFMFilename:=ChangeFileExt(NewBuf.Filename,'.lfm');
if FileExists(LFMFilename) then
NewBuf:=CodeToolBoss.LoadFile(LFMFilename)
else
NewBuf:=nil;
NewBuf:=nil;
if FileExists(LFMFilename) then begin
Result:=DoLoadCodeBuffer(NewBuf,LFMFilename,true,false);
if Result<>mrOk then exit;
Result:=mrCancel;
end;
end;
end;
@ -3472,7 +3478,8 @@ CheckHeap(IntToStr(GetMem_Cnt));
writeln('TMainIDE.DoOpenProjectFile B2');
if Project.MainUnit>=0 then begin
// read MainUnit Source
Result:=DoLoadCodeBuffer(NewBuf,Project.Units[Project.MainUnit].Filename);
Result:=DoLoadCodeBuffer(NewBuf,Project.Units[Project.MainUnit].Filename,
true,true);
writeln('TMainIDE.DoOpenProjectFile B3');
if Result=mrIgnore then Result:=mrAbort;
if Result=mrAbort then exit;
@ -4164,13 +4171,13 @@ begin
end;
function TMainIDE.DoLoadCodeBuffer(var ACodeBuffer: TCodeBuffer;
const AFilename: string): TModalResult;
const AFilename: string; UpdateFromDisk, Revert: boolean): TModalResult;
var
ACaption,AText:string;
begin
repeat
writeln('[TMainIDE.DoLoadCodeBuffer] A ',AFilename);
ACodeBuffer:=CodeToolBoss.LoadFile(AFilename);
ACodeBuffer:=CodeToolBoss.LoadFile(AFilename,UpdateFromDisk,Revert);
if ACodeBuffer<>nil then begin
ACodeBuffer.Reload;
Result:=mrOk;
@ -5270,6 +5277,9 @@ end.
{ =============================================================================
$Log$
Revision 1.179 2001/12/13 23:09:57 lazarus
MG: enhanced code caching, fixed CursorToCleanPos and beautify statement
Revision 1.178 2001/12/12 16:49:14 lazarus
Added code to disable save button when the active unit is not "modified".
Shane

View File

@ -364,7 +364,7 @@ var
NewSource: TCodeBuffer;
begin
repeat
NewSource:=CodeToolBoss.LoadFile(fFilename);
NewSource:=CodeToolBoss.LoadFile(fFilename,true,false);
if NewSource=nil then begin
ACaption:='Read error';
AText:='Unable to read file "'+fFilename+'"!';
@ -1269,6 +1269,9 @@ end.
{
$Log$
Revision 1.45 2001/12/13 23:09:58 lazarus
MG: enhanced code caching, fixed CursorToCleanPos and beautify statement
Revision 1.44 2001/12/02 11:03:36 lazarus
MG: added default pascal file extension option