diff --git a/ide/etfpcmsgparser.pas b/ide/etfpcmsgparser.pas index 8545b1ef0e..bde009c5e7 100644 --- a/ide/etfpcmsgparser.pas +++ b/ide/etfpcmsgparser.pas @@ -238,7 +238,7 @@ function FPCMsgFits(const Msg, Pattern: string; VarStarts: PPChar = nil; VarEnds: PPChar = nil // 10 PChars ): boolean; function GetFPCMsgValue1(const Src, Pattern: string; out Value1: string): boolean; -function GetFPCMsgValues(Src, Pattern: string; out Value1, Value2: string): boolean; +function GetFPCMsgValues2(Src, Pattern: string; out Value1, Value2: string): boolean; // not thread safe function IsFileInIDESrcDir(Filename: string): boolean; // (main thread) @@ -488,7 +488,7 @@ begin Result:=true; end; -function GetFPCMsgValues(Src, Pattern: string; out Value1, Value2: string +function GetFPCMsgValues2(Src, Pattern: string; out Value1, Value2: string ): boolean; { Pattern: 'Unit $1 was not found but $2 exists' Src: 'Unit dialogprocs was not found but dialogpr exists' @@ -2027,7 +2027,7 @@ procedure TIDEFPCParser.ImproveMsgLinkerUndefinedReference( begin Result:=false; if MsgLine.HasSourcePosition then exit; - if not etFPCMsgParser.GetFPCMsgValues(MsgLine.Msg,' _$1 in $2.o', + if not etFPCMsgParser.GetFPCMsgValues2(MsgLine.Msg,' _$1 in $2.o', MangledName,aUnitName) then exit; Result:=true; @@ -2816,7 +2816,7 @@ begin Result:=false; if Msg.MsgID<=0 then exit; if Msg.SubTool<>SubToolFPC then exit; - Result:=etFPCMsgParser.GetFPCMsgValues(Msg.Msg,GetFPCMsgPattern(Msg),Value1,Value2); + Result:=etFPCMsgParser.GetFPCMsgValues2(Msg.Msg,GetFPCMsgPattern(Msg),Value1,Value2); end; initialization diff --git a/ide/etquickfixes.pas b/ide/etquickfixes.pas index 830c51d3b7..a138b300d5 100644 --- a/ide/etquickfixes.pas +++ b/ide/etquickfixes.pas @@ -62,25 +62,6 @@ uses type - { TQuickFix_HideWithIDEDirective - hide with IDE directive %H- } - - TQuickFix_HideWithIDEDirective = class(TMsgQuickFix) - public - function IsApplicable(Msg: TMessageLine): boolean; - procedure CreateMenuItems(Fixes: TMsgQuickFixes); override; - procedure QuickFix(Fixes: TMsgQuickFixes; Msg: TMessageLine); override; - end; - - { TQuickFix_HideWithCompilerOption - hide with compiler option -vm } - - TQuickFix_HideWithCompilerOption = class(TMsgQuickFix) - public - function IsApplicable(Msg: TMessageLine; out ToolData: TIDEExternalToolData; - out IDETool: TObject): boolean; - procedure CreateMenuItems(Fixes: TMsgQuickFixes); override; - procedure QuickFix(Fixes: TMsgQuickFixes; Msg: TMessageLine); override; - end; - { TQuickFixIdentifierNotFoundAddLocal } TQuickFixIdentifierNotFoundAddLocal = class(TMsgQuickFix) @@ -120,6 +101,37 @@ type procedure QuickFix(Fixes: TMsgQuickFixes; Msg: TMessageLine); override; end; + { TQuickFixSrcPathOfPkgContains_OpenPkg + QuickFix for IDE warning "other sources path of package %s contains directory "%s", ..." + Open Package + } + + TQuickFixSrcPathOfPkgContains_OpenPkg = class(TMsgQuickFix) + public + function IsApplicable(Msg: TMessageLine; out PkgName: string): boolean; + procedure CreateMenuItems(Fixes: TMsgQuickFixes); override; + procedure QuickFix(Fixes: TMsgQuickFixes; Msg: TMessageLine); override; + end; + + { TQuickFix_HideWithIDEDirective - hide with IDE directive %H- } + + TQuickFix_HideWithIDEDirective = class(TMsgQuickFix) + public + function IsApplicable(Msg: TMessageLine): boolean; + procedure CreateMenuItems(Fixes: TMsgQuickFixes); override; + procedure QuickFix(Fixes: TMsgQuickFixes; Msg: TMessageLine); override; + end; + + { TQuickFix_HideWithCompilerOption - hide with compiler option -vm } + + TQuickFix_HideWithCompilerOption = class(TMsgQuickFix) + public + function IsApplicable(Msg: TMessageLine; out ToolData: TIDEExternalToolData; + out IDETool: TObject): boolean; + procedure CreateMenuItems(Fixes: TMsgQuickFixes); override; + procedure QuickFix(Fixes: TMsgQuickFixes; Msg: TMessageLine); override; + end; + { TIDEQuickFixes } TIDEQuickFixes = class(TMsgQuickFixes) @@ -184,6 +196,63 @@ begin Result:=true; end; +{ TQuickFixSrcPathOfPkgContains_OpenPkg } + +function TQuickFixSrcPathOfPkgContains_OpenPkg.IsApplicable(Msg: TMessageLine; + out PkgName: string): boolean; +var + Dir: string; + Pattern: String; + p: SizeInt; +begin + Result:=false; + if Msg=nil then exit; + if Msg.MsgID<>0 then exit; + + Pattern:=lisOtherSourcesPathOfPackageContainsDirectoryWhichIsA; + p:=Pos('%s',Pattern); + if p<1 then begin + debugln(['TQuickFixSrcPathOfPkgContains_OpenPkg.IsApplicable resourcestring misses %s: lisOtherSourcesPathOfPackageContainsDirectoryWhichIsA=',lisOtherSourcesPathOfPackageContainsDirectoryWhichIsA]); + exit; + end; + ReplaceSubstring(Pattern,p,2,'$1'); + p:=Pos('%s',Pattern); + if p<1 then begin + debugln(['TQuickFixSrcPathOfPkgContains_OpenPkg.IsApplicable resourcestring misses %s: lisOtherSourcesPathOfPackageContainsDirectoryWhichIsA=',lisOtherSourcesPathOfPackageContainsDirectoryWhichIsA]); + exit; + end; + ReplaceSubstring(Pattern,p,2,'$2'); + + if not GetFPCMsgValues2(Msg.Msg,Pattern,PkgName,Dir) then exit; + if PkgName='' then exit; + PkgName:=GetIdentifier(PChar(PkgName)); + Result:=IsValidIdent(PkgName); +end; + +procedure TQuickFixSrcPathOfPkgContains_OpenPkg.CreateMenuItems( + Fixes: TMsgQuickFixes); +var + i: Integer; + Msg: TMessageLine; + PkgName: string; +begin + for i:=0 to Fixes.LineCount-1 do begin + Msg:=Fixes.Lines[i]; + if not IsApplicable(Msg,PkgName) then continue; + Fixes.AddMenuItem(Self, Msg, 'Open package "'+PkgName+'"'); + exit; + end; +end; + +procedure TQuickFixSrcPathOfPkgContains_OpenPkg.QuickFix(Fixes: TMsgQuickFixes; + Msg: TMessageLine); +var + PkgName: string; +begin + if not IsApplicable(Msg,PkgName) then exit; + PackageEditingInterface.DoOpenPackageWithName(PkgName,[pofAddToRecent],false); +end; + { TQuickFix_HideWithCompilerOption } function TQuickFix_HideWithCompilerOption.IsApplicable(Msg: TMessageLine; out @@ -765,12 +834,15 @@ begin fMenuItemToInfo:=TPointerToPointerTree.Create; // init standard quickfixes - IDEQuickFixes.RegisterQuickFix(TQuickFix_HideWithIDEDirective.Create); + // add them in the order of usefulness IDEQuickFixes.RegisterQuickFix(TQuickFixIdentifierNotFoundAddLocal.Create); IDEQuickFixes.RegisterQuickFix(TQuickFixLocalVariableNotUsed_Remove.Create); IDEQuickFixes.RegisterQuickFix(TQuickFixUnitNotFound_Remove.Create); IDEQuickFixes.RegisterQuickFix(TQuickFixClassWithAbstractMethods.Create); + IDEQuickFixes.RegisterQuickFix(TQuickFixSrcPathOfPkgContains_OpenPkg.Create); + // add as last (no fix, just hide message) + IDEQuickFixes.RegisterQuickFix(TQuickFix_HideWithIDEDirective.Create); IDEQuickFixes.RegisterQuickFix(TQuickFix_HideWithCompilerOption.Create); end; diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index 48e86b0151..e1bea7f977 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -3887,6 +3887,9 @@ resourcestring lisPkgMangTheFollowingPackageFailedToLoad = 'The following package failed to load:'; lisPkgMangTheFollowingPackagesFailedToLoad = 'The following packages failed to load:'; lisMissingPackages = 'Missing Packages'; + lisOtherSourcesPathOfPackageContainsDirectoryWhichIsA = 'other sources path ' + +'of package %s contains directory "%s", which is already in the unit ' + +'search path.'; lisPkgManginvalidCompilerFilename = 'invalid Compiler filename'; lisPkgMangTheCompilerFileForPackageIsNotAValidExecutable = 'The compiler ' +'file for package %s is not a valid executable:%s%s'; diff --git a/packager/pkgmanager.pas b/packager/pkgmanager.pas index 9c0fe1e5b0..2cb63e04a4 100644 --- a/packager/pkgmanager.pas +++ b/packager/pkgmanager.pas @@ -2641,7 +2641,9 @@ var Dir:=GetNextDirectoryInSearchPath(UnparsedSrcPath,p); if Dir='' then exit; if SearchDirectoryInSearchPath(UnparsedUnitPath,Dir)>0 then begin - s:='other sources path of '+aCompilerOptions.GetOwnerName+' contains directory "'+Dir+'", which is already in the unit search path.'; + // Note: when changing this, update TQuickFixSrcPathOfPkgContains_OpenPkg + s:=Format(lisOtherSourcesPathOfPackageContainsDirectoryWhichIsA, [ + aCompilerOptions.GetOwnerName, Dir]); debugln(['CheckSrcPathIsInUnitPath WARNING: ',s]); { ToDo: ask user and remove dir from unit path } IDEMessagesWindow.AddCustomMessage(mluWarning,s);