mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-08 17:27:33 +01:00
IDE: fpc parser: find ld message file:line: msg
git-svn-id: trunk@45186 -
This commit is contained in:
parent
53ca8fe17d
commit
04d59be9be
@ -167,6 +167,8 @@ type
|
||||
procedure ImproveMsgUnitNotUsed(aSynchronized: boolean; MsgLine: TMessageLine);
|
||||
procedure ImproveMsgUnitNotFound(aSynchronized: boolean;
|
||||
MsgLine: TMessageLine);
|
||||
procedure ImproveMsgLinkerUndefinedReference(aSynchronized: boolean;
|
||||
MsgLine: TMessageLine);
|
||||
procedure Translate(p: PChar; MsgItem, TranslatedItem: TFPCMsgItem;
|
||||
out TranslatedMsg: String; out MsgType: TMessageLineUrgency);
|
||||
function LongenFilename(MsgLine: TMessageLine; aFilename: string): string; // (worker thread)
|
||||
@ -1386,6 +1388,9 @@ For example:
|
||||
Examples for linking errors:
|
||||
linkerror.o(.text$_main+0x9):linkerror.pas: undefined reference to `NonExistingFunction'
|
||||
|
||||
/path/lib/x86_64-linux/blaunit.o: In function `FORMCREATE':
|
||||
/path//blaunit.pas:45: undefined reference to `BLAUNIT_BLABLA'
|
||||
|
||||
Closing script ppas.sh
|
||||
|
||||
Mac OS X linker example:
|
||||
@ -1420,7 +1425,7 @@ begin
|
||||
MsgLine:=inherited CreateMsgLine(i);
|
||||
MsgLine.MsgID:=0;
|
||||
MsgLine.SubTool:=SubToolFPCLinker;
|
||||
MsgLine.Urgency:=mluWarning;
|
||||
MsgLine.Urgency:=mluImportant;
|
||||
AddMsgLine(MsgLine);
|
||||
end;
|
||||
end;
|
||||
@ -1780,6 +1785,67 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIDEFPCParser.ImproveMsgLinkerUndefinedReference(
|
||||
aSynchronized: boolean; MsgLine: TMessageLine);
|
||||
{ For example:
|
||||
/path/lib/x86_64-linux/blaunit.o: In function `FORMCREATE':
|
||||
/path//blaunit.pas:45: undefined reference to `BLAUNIT_BLABLA'
|
||||
}
|
||||
|
||||
function CheckForFileAndLineNumber: boolean;
|
||||
var
|
||||
p: PChar;
|
||||
Msg: String;
|
||||
aFilename: String;
|
||||
LineNumber: Integer;
|
||||
i: SizeInt;
|
||||
begin
|
||||
Result:=false;
|
||||
if aSynchronized then exit;
|
||||
if MsgLine.HasSourcePosition then exit;
|
||||
Msg:=MsgLine.Msg;
|
||||
p:=PChar(Msg);
|
||||
// check for "filename:decimals: message"
|
||||
// or unit1.o(.text+0x3a):unit1.pas:48: undefined reference to `DoesNotExist'
|
||||
|
||||
// read filename
|
||||
repeat
|
||||
if p^=#0 then exit;
|
||||
inc(p);
|
||||
until (p^=':') and (p[1] in ['0'..'9']);
|
||||
aFilename:=LeftStr(Msg,p-PChar(Msg));
|
||||
// check for something):filename
|
||||
i:=Pos('):',aFilename);
|
||||
if i>0 then
|
||||
Delete(aFilename,1,i+1);
|
||||
aFilename:=TrimFilename(aFilename);
|
||||
|
||||
// read line number
|
||||
inc(p);
|
||||
LineNumber:=0;
|
||||
while p^ in ['0'..'9'] do begin
|
||||
LineNumber:=LineNumber*10+ord(p^)-ord('0');
|
||||
if LineNumber>9999999 then exit;
|
||||
inc(p);
|
||||
end;
|
||||
if p^<>':' then exit;
|
||||
inc(p);
|
||||
while p^ in [' '] do inc(p);
|
||||
|
||||
Result:=true;
|
||||
MsgLine.Msg:=copy(Msg,p-PChar(Msg)+1,length(Msg));
|
||||
MsgLine.Filename:=aFilename;
|
||||
MsgLine.Line:=LineNumber;
|
||||
MsgLine.Column:=1;
|
||||
MsgLine.Urgency:=mluError;
|
||||
end;
|
||||
|
||||
begin
|
||||
if MsgLine.SubTool<>SubToolFPCLinker then exit;
|
||||
|
||||
if CheckForFileAndLineNumber then exit;
|
||||
end;
|
||||
|
||||
procedure TIDEFPCParser.Translate(p: PChar; MsgItem, TranslatedItem: TFPCMsgItem;
|
||||
out TranslatedMsg: String; out MsgType: TMessageLineUrgency);
|
||||
begin
|
||||
@ -2168,7 +2234,7 @@ begin
|
||||
then begin
|
||||
// try to find for short file name the full file name
|
||||
aFilename:=MsgLine.Filename;
|
||||
if not FilenameIsAbsolute(aFilename) then begin
|
||||
if (not FilenameIsAbsolute(aFilename)) then begin
|
||||
MsgWorkerDir:=MsgLine.Attribute[FPCMsgAttrWorkerDirectory];
|
||||
if fIncludePathValidForWorkerDir<>MsgWorkerDir then begin
|
||||
// fetch include path
|
||||
@ -2218,6 +2284,8 @@ begin
|
||||
ImproveMsgUnitNotFound(aSynchronized, MsgLine);
|
||||
ImproveMsgUnitNotUsed(aSynchronized, MsgLine);
|
||||
ImproveMsgSenderNotUsed(aSynchronized, MsgLine);
|
||||
end else if MsgLine.SubTool=SubToolFPCLinker then begin
|
||||
ImproveMsgLinkerUndefinedReference(aSynchronized, MsgLine);
|
||||
end;
|
||||
end;
|
||||
fLastWorkerImprovedMessage[aSynchronized]:=Tool.WorkerMessages.Count-1;
|
||||
|
||||
@ -3336,18 +3336,18 @@ end;
|
||||
|
||||
procedure TMessagesFrame.ShowIDMenuItemClick(Sender: TObject);
|
||||
begin
|
||||
if MsgShowIDMenuItem.Checked then
|
||||
MessagesCtrl.Options:=MessagesCtrl.Options+[mcoShowMessageID]
|
||||
if mcoShowMessageID in MessagesCtrl.Options then
|
||||
MessagesCtrl.Options:=MessagesCtrl.Options-[mcoShowMessageID]
|
||||
else
|
||||
MessagesCtrl.Options:=MessagesCtrl.Options-[mcoShowMessageID];
|
||||
MessagesCtrl.Options:=MessagesCtrl.Options+[mcoShowMessageID];
|
||||
end;
|
||||
|
||||
procedure TMessagesFrame.TranslateMenuItemClick(Sender: TObject);
|
||||
begin
|
||||
if MsgTranslateMenuItem.Checked then
|
||||
MessagesCtrl.Options:=MessagesCtrl.Options+[mcoShowTranslated]
|
||||
if mcoShowTranslated in MessagesCtrl.Options then
|
||||
MessagesCtrl.Options:=MessagesCtrl.Options-[mcoShowTranslated]
|
||||
else
|
||||
MessagesCtrl.Options:=MessagesCtrl.Options-[mcoShowTranslated];
|
||||
MessagesCtrl.Options:=MessagesCtrl.Options+[mcoShowTranslated];
|
||||
end;
|
||||
|
||||
procedure TMessagesFrame.UnhideMsgTypeClick(Sender: TObject);
|
||||
@ -3428,7 +3428,7 @@ end;
|
||||
|
||||
procedure TMessagesFrame.HideHintsWithoutPosMenuItemClick(Sender: TObject);
|
||||
begin
|
||||
MessagesCtrl.ActiveFilter.HideNotesWithoutPos:=MsgHideHintsWithoutPosMenuItem.Checked;
|
||||
MessagesCtrl.ActiveFilter.HideNotesWithoutPos:=not MessagesCtrl.ActiveFilter.HideNotesWithoutPos;
|
||||
end;
|
||||
|
||||
procedure TMessagesFrame.HideMsgOfTypeMenuItemClick(Sender: TObject);
|
||||
|
||||
@ -98,7 +98,7 @@ type
|
||||
|
||||
TQuickFixClassWithAbstractMethods = class(TMsgQuickFix)
|
||||
public
|
||||
function IsApplicable(Msg: TMessageLine): boolean;
|
||||
function IsApplicable(Msg: TMessageLine; out aClassName, aMethodName: string): boolean;
|
||||
procedure CreateMenuItems(Fixes: TMsgQuickFixes); override;
|
||||
procedure QuickFix(Fixes: TMsgQuickFixes; Msg: TMessageLine); override;
|
||||
end;
|
||||
@ -182,7 +182,7 @@ begin
|
||||
// Check: Local variable "$1" not used
|
||||
if not TIDEFPCParser.MsgLineIsId(Msg,5025,Identifier,Dummy) then
|
||||
exit;
|
||||
if not IsValidIdent(Identifier) then exit;
|
||||
if not Msg.HasSourcePosition or not IsValidIdent(Identifier) then exit;
|
||||
|
||||
// check if message position is at end of identifier
|
||||
// (FPC gives position of start or end of identifier)
|
||||
@ -253,21 +253,13 @@ end;
|
||||
|
||||
{ TQuickFixClassWithAbstractMethods }
|
||||
|
||||
function TQuickFixClassWithAbstractMethods.IsApplicable(Msg: TMessageLine
|
||||
): boolean;
|
||||
var
|
||||
aClassName: string;
|
||||
aMethodName: string;
|
||||
function TQuickFixClassWithAbstractMethods.IsApplicable(Msg: TMessageLine; out
|
||||
aClassName, aMethodName: string): boolean;
|
||||
begin
|
||||
Result:=false;
|
||||
if (Msg.SubTool<>SubToolFPC)
|
||||
or (Msg.MsgID<>4046) // Constructing a class "$1" with abstract method "$2"
|
||||
or (not Msg.HasSourcePosition)
|
||||
then exit;
|
||||
if not IDEFPCParser.GetFPCMsgValues(Msg,aClassName,aMethodName) then begin
|
||||
debugln(['TQuickFixClassWithAbstractMethods.IsApplicable can not extract values: ',Msg.Msg]);
|
||||
exit;
|
||||
end;
|
||||
// Check: Constructing a class "$1" with abstract method "$2"
|
||||
if not IDEFPCParser.MsgLineIsId(Msg,4046,aClassname,aMethodName) then exit;
|
||||
if (not Msg.HasSourcePosition) then exit;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
@ -280,8 +272,7 @@ var
|
||||
begin
|
||||
if Fixes.LineCount<>1 then exit;
|
||||
Msg:=Fixes.Lines[0];
|
||||
if not IsApplicable(Msg) then exit;
|
||||
if not IDEFPCParser.GetFPCMsgValues(Msg,aClassName,aMethodName) then exit;
|
||||
if not IsApplicable(Msg,aClassName,aMethodName) then exit;
|
||||
Fixes.AddMenuItem(Self,Msg,'Show abstract methods of "'+aClassName+'"');
|
||||
end;
|
||||
|
||||
@ -297,11 +288,7 @@ var
|
||||
NewY: integer;
|
||||
NewTopLine: integer;
|
||||
begin
|
||||
if not IsApplicable(Msg) then exit;
|
||||
if not IDEFPCParser.GetFPCMsgValues(Msg,aClassName,aMethodName) then begin
|
||||
debugln(['TQuickFixClassWithAbstractMethods.QuickFix invalid message ',Msg.Msg]);
|
||||
exit;
|
||||
end;
|
||||
if not IsApplicable(Msg,aClassName,aMethodName) then exit;
|
||||
|
||||
if not LazarusIDE.BeginCodeTools then begin
|
||||
DebugLn(['TQuickFixClassWithAbstractMethods failed because IDE busy']);
|
||||
@ -353,6 +340,7 @@ function TQuickFixUnitNotFound_Remove.IsApplicable(Msg: TMessageLine; out
|
||||
MissingUnitName, UsedByUnit: string): boolean;
|
||||
begin
|
||||
Result:=false;
|
||||
if Msg=nil then exit;
|
||||
if (Msg.SubTool<>SubToolFPC)
|
||||
or (not Msg.HasSourcePosition)
|
||||
or ((Msg.MsgID<>5023) // Unit "$1" not used in $2
|
||||
@ -423,14 +411,13 @@ var
|
||||
CleanPos: integer;
|
||||
Node: TCodeTreeNode;
|
||||
Identifier: String;
|
||||
Dummy: string;
|
||||
begin
|
||||
Result:=false;
|
||||
if (Msg.SubTool<>SubToolFPC)
|
||||
or (Msg.MsgID<>5000) // identifier not found "$1"
|
||||
or (not Msg.HasSourcePosition)
|
||||
then exit;
|
||||
Identifier:=IDEFPCParser.GetFPCMsgValue1(Msg);
|
||||
if not IsValidIdent(Identifier) then exit;
|
||||
// check: identifier not found "$1"
|
||||
if not IDEFPCParser.MsgLineIsId(Msg,5000,Identifier,Dummy) then
|
||||
exit;
|
||||
if not Msg.HasSourcePosition or not IsValidIdent(Identifier) then exit;
|
||||
|
||||
// check if message position is at end of identifier
|
||||
// (FPC gives position of end of identifier)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user