IDE: further migration external tools

git-svn-id: trunk@42342 -
This commit is contained in:
mattias 2013-08-05 07:26:12 +00:00
parent 8dbd0fbb61
commit f7c7f989ee
6 changed files with 210 additions and 29 deletions

View File

@ -16,7 +16,7 @@ interface
uses
Classes, SysUtils, typinfo, contnrs, UTF8Process, AvgLvlTree,
LazMethodList, LazLogger, LazFileUtils, LazFileCache, Menus;
LazMethodList, LazLogger, LazFileUtils, LazFileCache, Menus, LCLProc;
const
SubToolFPC = 'FPC';
@ -531,6 +531,48 @@ type
var
ExternalToolList: TIDEExternalTools = nil; // will be set by the IDE
type
{ TIDEExternalToolOptions }
TETMacroFunction = function(var aValue: string): boolean of object;
TIDEExternalToolOptions = class
private
fCmdLineParams: string;
FCustomMacroFunction: TETMacroFunction;
FEnvironmentOverrides: TStringList;
FExecutable: string;
FQuiet: boolean;
FResolveMacros: boolean;
FScanners: TStrings;
fTitle: string;
fWorkingDirectory: string;
procedure SetEnvironmentOverrides(AValue: TStringList);
procedure SetScanners(AValue: TStrings);
public
constructor Create;
destructor Destroy; override;
procedure Assign(Source: TIDEExternalToolOptions);
function Equals(Obj: TObject): boolean; override;
procedure Clear;
property Title: string read fTitle write fTitle;
property Executable: string read FExecutable write FExecutable;
property CmdLineParams: string read fCmdLineParams write fCmdLineParams;
property WorkingDirectory: string read fWorkingDirectory write fWorkingDirectory;
property EnvironmentOverrides: TStringList read FEnvironmentOverrides write SetEnvironmentOverrides;
property Scanners: TStrings read FScanners write SetScanners;
property ResolveMacros: boolean read FResolveMacros write FResolveMacros default true;
property CustomMacroFunction: TETMacroFunction read FCustomMacroFunction write FCustomMacroFunction;
property Quiet: boolean read FQuiet write FQuiet; // no user dialogs about errors
end;
type
TRunExternalTool = function(Tool: TIDEExternalToolOptions): boolean of object;
var
RunExternalTool: TRunExternalTool = nil;// set by the IDE
function CompareMsgLinesSrcPos(MsgLine1, MsgLine2: Pointer): integer;
function dbgs(u: TMessageLineUrgency): string; overload;
@ -593,6 +635,80 @@ begin
WriteStr(Result,s);
end;
{ TIDEExternalToolOptions }
procedure TIDEExternalToolOptions.SetEnvironmentOverrides(AValue: TStringList);
begin
if FEnvironmentOverrides.Equals(AValue) then Exit;
FEnvironmentOverrides.Assign(AValue);
end;
procedure TIDEExternalToolOptions.SetScanners(AValue: TStrings);
begin
if FScanners.Equals(AValue) then Exit;
FScanners.Assign(AValue);
end;
constructor TIDEExternalToolOptions.Create;
begin
ResolveMacros:=true;
FEnvironmentOverrides:=TStringList.Create;
FScanners:=TStringList.Create;
end;
destructor TIDEExternalToolOptions.Destroy;
begin
FreeAndNil(FEnvironmentOverrides);
FreeAndNil(FScanners);
inherited Destroy;
end;
procedure TIDEExternalToolOptions.Assign(Source: TIDEExternalToolOptions);
begin
Title:=Source.Title;
Executable:=Source.Executable;
CmdLineParams:=Source.CmdLineParams;
WorkingDirectory:=Source.WorkingDirectory;
EnvironmentOverrides:=Source.EnvironmentOverrides;
Scanners:=Source.Scanners;
ResolveMacros:=Source.ResolveMacros;
CustomMacroFunction:=Source.CustomMacroFunction;
Quiet:=Source.Quiet;
end;
function TIDEExternalToolOptions.Equals(Obj: TObject): boolean;
var
Source: TIDEExternalToolOptions;
begin
if Obj=Self then exit(true);
if Obj is TIDEExternalToolOptions then begin
Source:=TIDEExternalToolOptions(Obj);
Result:=(Title=Source.Title)
and (Executable=Source.Executable)
and (CmdLineParams=Source.CmdLineParams)
and (WorkingDirectory=Source.WorkingDirectory)
and EnvironmentOverrides.Equals(Source.EnvironmentOverrides)
and Scanners.Equals(Source.Scanners)
and (ResolveMacros=Source.ResolveMacros)
and CompareMethods(TMethod(CustomMacroFunction),TMethod(Source.CustomMacroFunction))
and (Quiet=Source.Quiet);
end else
Result:=inherited Equals(Obj);
end;
procedure TIDEExternalToolOptions.Clear;
begin
fCmdLineParams:='';
FCustomMacroFunction:=nil;
FEnvironmentOverrides.Clear;
FExecutable:='';
FResolveMacros:=true;
FScanners.Clear;
fTitle:='';
fWorkingDirectory:='';
FQuiet:=false;
end;
{ TExternalToolGroup }
function TExternalToolGroup.GetItems(Index: integer): TAbstractExternalTool;
@ -949,6 +1065,11 @@ function TAbstractExternalTool.AddParser(ParserClass: TExtToolParserClass
var
i: Integer;
begin
for i:=0 to ParserCount-1 do begin
Result:=Parsers[i];
if Result.ClassType=ParserClass then
exit;
end;
Result:=ParserClass.Create(nil);
i:=0;
while (i<FParsers.Count) and (Parsers[i].Priority>=ParserClass.Priority) do

View File

@ -285,13 +285,13 @@ type
// progress and error messages
function ShowProgress(const SomeText: string;
Step, MaxStep: integer): boolean; virtual; abstract; // False if canceled by user
function DoJumpToCompilerMessage(
function DoJumpToCompilerMessage(FocusEditor: boolean;
{$IFDEF EnableNewExtTools}
Msg: TMessageLine; // if nil then it jumps to first message
Msg: TMessageLine = nil // if nil then it jumps to first message
{$ELSE}
Index:integer;
Index:integer = -1
{$ENDIF}
FocusEditor: boolean): boolean; virtual; abstract;
): boolean; virtual; abstract;
procedure DoJumpToNextError(DirectionDown: boolean); virtual; abstract;
procedure DoShowMessagesView(BringToFront: boolean = true); virtual; abstract;
function DoCheckFilesOnDisk(Instantaneous: boolean = false): TModalResult; virtual; abstract;

View File

@ -694,7 +694,7 @@ begin
LfmFixer.RootMustBeClassInIntf:=true;
LfmFixer.ObjectsMustExist:=true;
if LfmFixer.ConvertAndRepair<>mrOK then begin
LazarusIDE.DoJumpToCompilerMessage({$IFDEF EnableNewExtTools}nil{$ELSE}-1{$ENDIF},true);
LazarusIDE.DoJumpToCompilerMessage(true);
fOwnerConverter.fErrorMsg:='Problems when repairing form file '
+ChangeFileExt(fOrigUnitFilename, '.lfm');
exit(mrAbort);

View File

@ -124,10 +124,15 @@ type
procedure Clear; inline;
function Equals(Obj: TObject): boolean; override;
procedure Assign(Src: TExternalToolMenuItems);
function Count: integer; inline;
property Items[Index: integer]: TExternalToolMenuItem read GetItems; default;
procedure Add(Item: TExternalToolMenuItem);
procedure Insert(Index: integer; Item: TExternalToolMenuItem);
procedure Delete(Index: integer);
procedure Move(CurIndex, NewIndex: integer);
// run
function Run(Index: integer; ShowAbort: boolean): TModalResult;
// load/save
function Load(Config: TConfigStorage): TModalResult;
function Load(Config: TConfigStorage; const Path: string): TModalResult;
override;
@ -136,8 +141,6 @@ type
override;
procedure LoadShortCuts(KeyCommandRelationList: TKeyCommandRelationList);
procedure SaveShortCuts(KeyCommandRelationList: TKeyCommandRelationList);
function Count: integer; inline;
property Items[Index: integer]: TExternalToolMenuItem read GetItems; default;
end;
var
@ -535,6 +538,56 @@ begin
fItems.Move(CurIndex,NewIndex);
end;
function TExternalToolMenuItems.Run(Index: integer; ShowAbort: boolean
): TModalResult;
var
Item: TExternalToolMenuItem;
function ResolveMacros(const Value: string; out NewValue: string): boolean;
begin
NewValue:=Value;
Result:=GlobalMacroList.SubstituteStr(NewValue);
if not Result then exit;
Run:=IDEMessageDialogAb('Invalid macro','Invalid macro in tool "'+Item.Title+'":'#13+Value,
mtError,[mbCancel],ShowAbort);
end;
var
Tool: TAbstractExternalTool;
Executable: String;
CmdLineParams: string;
WorkingDirectory: string;
i: Integer;
s: String;
EnvironmentOverrides: TStringList;
begin
Result:=mrCancel;
Item:=Items[Index];
if not ResolveMacros(Item.Filename,Executable) then exit;
if not ResolveMacros(Item.CmdLineParams,CmdLineParams) then exit;
if not ResolveMacros(Item.WorkingDirectory,WorkingDirectory) then exit;
EnvironmentOverrides:=TStringList.Create;
try
for i:=0 to Item.EnvironmentOverrides.Count-1 do begin
if not ResolveMacros(Item.EnvironmentOverrides[i],s) then exit;
if s<>'' then
EnvironmentOverrides.Add(s);
end;
Tool:=ExternalToolList.Add(Item.Title);
Tool.Process.Executable:=Item.Title;
Tool.Process.CurrentDirectory:=WorkingDirectory;
Tool.CmdLineParams:=CmdLineParams;
for i:=0 to Item.Scanners.Count-1 do
Tool.AddParsers(Item.Scanners[i]);
Tool.EnvironmentOverrides:=EnvironmentOverrides;
Tool.Execute;
if Tool.ParserCount>0 then
Tool.WaitForExit;
finally
EnvironmentOverrides.Free;
end;
end;
function TExternalToolMenuItems.Load(Config: TConfigStorage): TModalResult;
var
i: integer;

View File

@ -843,9 +843,7 @@ type
// external tools
function PrepareForCompile: TModalResult; override;
{$IFNDEF EnableNewExtTools}
function OnRunExternalTool(Tool: TIDEExternalToolOptions): TModalResult;
{$ENDIF}
function OnRunExternalTool(Tool: TIDEExternalToolOptions): {$IFDEF EnableNewExtTools}boolean{$ELSE}TModalResult{$ENDIF};
function DoRunExternalTool(Index: integer; ShowAbort: Boolean): TModalResult;
function DoSaveBuildIDEConfigs(Flags: TBuildLazarusFlags): TModalResult; override;
function DoExampleManager: TModalResult; override;
@ -970,13 +968,13 @@ type
function DoConvertDelphiPackage(const DelphiFilename: string): TModalResult;
// message view
function DoJumpToCompilerMessage(
function DoJumpToCompilerMessage(FocusEditor: boolean;
{$IFDEF EnableNewExtTools}
Msg: TMessageLine;
Msg: TMessageLine = nil
{$ELSE}
Index:integer;
Index:integer = -1
{$ENDIF}
FocusEditor: boolean): boolean; override;
): boolean; override;
procedure DoJumpToNextError(DirectionDown: boolean); override;
procedure DoShowMessagesView(BringToFront: boolean = true); override;
@ -1343,8 +1341,8 @@ begin
FWaitForClose := False;
SetupDialogs;
{$IFNDEF EnableNewExtTools}
RunExternalTool:=@OnRunExternalTool;
{$IFNDEF EnableNewExtTools}
{$IFDEF UseAsyncProcess}
if Widgetset.GetLCLCapability(lcAsyncProcess) = 1 then
TOutputFilterProcess := TAsyncProcess
@ -6896,7 +6894,9 @@ var
NeedBuildAllFlag: Boolean;
UnitOutputDirectory: String;
TargetExeName: String;
{$IFNDEF EnableNewExtTools}
err: TFPCErrorType;
{$ENDIF}
TargetExeDirectory: String;
FPCVersion, FPCRelease, FPCPatch: integer;
Note: String;
@ -6928,7 +6928,9 @@ begin
// show messages
IDEWindowCreators.ShowForm(MessagesView,EnvironmentOptions.MsgViewFocus);
{$IFNDEF EnableNewExtTools}
MessagesView.BeginBlock;
{$ENDIF}
try
Result:=DoSaveForBuild(AReason);
if Result<>mrOk then begin
@ -7145,7 +7147,7 @@ begin
Project1.LastCompilerFilename:=CompilerFilename;
Project1.LastCompilerParams:=CompilerParams;
Project1.LastCompilerFileDate:=FileAgeCached(CompilerFilename);
DoJumpToCompilerMessage(-1,not EnvironmentOptions.ShowCompileDialog);
DoJumpToCompilerMessage(not EnvironmentOptions.ShowCompileDialog);
CompileProgress.Ready(lisInfoBuildError);
debugln(['TMainIDE.DoBuildProject Compile failed']);
exit;
@ -7195,15 +7197,18 @@ begin
end;
Project1.ProjResources.DoAfterBuild(AReason, Project1.IsVirtual);
{$IFNDEF EnableNewExtTools}
// add success message
MessagesView.AddMsg(Format(lisProjectSuccessfullyBuilt, ['"',
Project1.GetTitleOrName, '"']),'',-1);
{$ENDIF}
CompileProgress.Ready(lisInfoBuildSuccess);
finally
// check sources
DoCheckFilesOnDisk;
{$IFNDEF EnableNewExtTools}
MessagesView.EndBlock;
{$ENDIF}
end;
IDEWindowCreators.ShowForm(MessagesView,EnvironmentOptions.MsgViewFocus);
Result:=mrOk;
@ -7484,7 +7489,11 @@ end;
function TMainIDE.DoRunExternalTool(Index: integer; ShowAbort: Boolean): TModalResult;
begin
SourceEditorManager.ClearErrorLines;
{$IFDEF EnableNewExtTools}
Result:=ExternalToolMenuItems.Run(Index,ShowAbort);
{$ELSE}
Result:=ExternalTools.Run(Index,GlobalMacroList,ShowAbort);
{$ENDIF}
DoCheckFilesOnDisk;
end;
@ -8113,14 +8122,12 @@ begin
MainBuildBoss.RescanCompilerDefines(false,false,false,false);
end;
{$IFNDEF EnableNewExtTools}
function TMainIDE.OnRunExternalTool(Tool: TIDEExternalToolOptions): TModalResult;
function TMainIDE.OnRunExternalTool(Tool: TIDEExternalToolOptions): {$IFDEF EnableNewExtTools}boolean{$ELSE}TModalResult{$ENDIF};
begin
SourceEditorManager.ClearErrorLines;
Result:=ExternalTools.Run(Tool,GlobalMacroList,false);
DoCheckFilesOnDisk;
end;
{$ENDIF}
function TMainIDE.DoCheckSyntax: TModalResult;
var
@ -8880,13 +8887,13 @@ begin
ErrType:=FPCErrorTypeNameToType(ALine.Parts.Values['Type']);
end;
function TMainIDE.DoJumpToCompilerMessage(
function TMainIDE.DoJumpToCompilerMessage(FocusEditor: boolean;
{$IFDEF EnableNewExtTools}
Msg: TMessageLine;
Msg: TMessageLine
{$ELSE}
Index:integer;
Index:integer
{$ENDIF}
FocusEditor: boolean): boolean;
): boolean;
var
MaxMessages: integer;
Filename, SearchedFilename: string;
@ -9032,7 +9039,7 @@ begin
end;
end;
MessagesView.SelectedMessageIndex:=Index;
DoJumpToCompilerMessage(Index,true);
DoJumpToCompilerMessage(true,Index);
end;
function TMainIDE.DoJumpToSearchResult(FocusEditor: boolean): boolean;
@ -11188,7 +11195,7 @@ end;
{$IFNDEF EnableNewExtTools}
procedure TMainIDE.MessagesViewSelectionChanged(sender: TObject);
begin
DoJumpToCompilerMessage(TMessagesView(Sender).SelectedMessageIndex,True);
DoJumpToCompilerMessage(True,TMessagesView(Sender).SelectedMessageIndex);
end;
{$ENDIF}
@ -12916,7 +12923,7 @@ begin
if ToolStatus=itBuilder then
ToolStatus:=itNone;
if ErrorOccurred then
DoJumpToCompilerMessage(-1,true);
DoJumpToCompilerMessage(true);
end;
{$ENDIF}

View File

@ -3943,7 +3943,7 @@ begin
mtInformation,[mbOk],'');
end;
end else begin
MainIDE.DoJumpToCompilerMessage({$IFDEF EnableNewExtTools}nil{$ELSE}-1{$ENDIF},true);
MainIDE.DoJumpToCompilerMessage(true);
Result:=mrAbort;
exit;
end;