IDE: started pas2js message parser

git-svn-id: trunk@57902 -
This commit is contained in:
mattias 2018-05-11 19:59:48 +00:00
parent 536ffd588f
commit 157312616b
8 changed files with 227 additions and 33 deletions

2
.gitattributes vendored
View File

@ -6706,6 +6706,7 @@ ide/etmessageframe.lfm svneol=native#text/plain
ide/etmessageframe.pas svneol=native#text/plain
ide/etmessageswnd.lfm svneol=native#text/plain
ide/etmessageswnd.pas svneol=native#text/plain
ide/etpas2jsmsgparser.pas svneol=native#text/plain
ide/etquickfixes.pas svneol=native#text/plain
ide/etsrceditmarks.pas svneol=native#text/plain
ide/examplemanager.lfm svneol=native#text/plain
@ -6956,6 +6957,7 @@ ide/newprojectdlg.lfm svneol=native#text/plain
ide/newprojectdlg.pp svneol=native#text/pascal
ide/notifyprocessend.pas svneol=native#text/pascal
ide/objectlists.pas svneol=native#text/pascal
ide/pas2jsmsg.txt svneol=native#text/plain
ide/patheditordlg.lfm svneol=native#text/pascal
ide/patheditordlg.pas svneol=native#text/pascal
ide/procedurelist.lfm svneol=native#text/plain

View File

@ -370,6 +370,7 @@ type
UseCache: boolean = true): string;// value of macro #FPCUnitPath
procedure GetFPCVersionForDirectory(const Directory: string;
out FPCVersion, FPCRelease, FPCPatch: integer);
function GetPCVersionForDirectory(const Directory: string): integer;
function GetNamespacesForDirectory(const Directory: string;
UseCache: boolean = true): string;// value of macro #Namespaces
@ -1698,6 +1699,23 @@ begin
FPCPatch:=FPCFullVersion mod 100;
end;
function TCodeToolManager.GetPCVersionForDirectory(const Directory: string
): integer;
var
Evaluator: TExpressionEvaluator;
s: String;
begin
Result:=0;
Evaluator:=DefineTree.GetDefinesForDirectory(Directory,true);
if Evaluator=nil then exit;
s:=Evaluator['FPC_FULLVERSION'];
if s<>'' then
exit(StrToIntDef(s,0));
s:=Evaluator['PAS2JS_FULLVERSION'];
if s<>'' then
exit(StrToIntDef(s,0));
end;
function TCodeToolManager.GetNamespacesForDirectory(const Directory: string;
UseCache: boolean): string;
var

View File

@ -30,6 +30,9 @@ const
SubToolFPCWindRes = 'FPCWindRes';
SubToolFPCAssembler = 'FPCAssembler';
SubToolPas2js = 'Pas2JS';
SubToolPas2jsPriority = 101;
SubToolMake = 'make';
SubToolMakePriority = 1000; // higher than FPC
@ -347,6 +350,7 @@ type
TFPCParserClass = class of TFPCParser;
var
IDEFPCParser: TFPCParserClass = nil;
IDEPas2jsParser: TFPCParserClass = nil;
type
{ TMakeParser - standard parser for 'make' messages, implemented by IDE }

View File

@ -51,7 +51,7 @@ uses
IDECmdLine, LazarusIDEStrConsts, DialogProcs, IDEProcs, IDEUtils,
InputHistory, EditDefineTree, ProjectResources, MiscOptions, LazConf,
EnvironmentOpts, TransferMacros, CompilerOptions,
ExtTools, etMakeMsgParser, etFPCMsgParser,
ExtTools, etMakeMsgParser, etFPCMsgParser, etPas2jsMsgParser,
Compiler, FPCSrcScan, PackageDefs, PackageSystem, Project, ProjectIcon,
ModeMatrixOpts, BaseBuildManager, ApplicationBundle, RunParamsOpts;
@ -529,6 +529,7 @@ begin
ExternalToolList.RegisterParser(TDefaultParser);
FPCMsgFilePool:=TFPCMsgFilePool.Create(nil);
Pas2jsMsgFilePool:=TPas2jsMsgFilePool.Create(nil);
end;
procedure TBuildManager.SetupCompilerInterface;

View File

@ -111,7 +111,7 @@ type
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function LoadCurrentEnglishFile(UpdateFromDisk: boolean;
AThread: TThread): TFPCMsgFilePoolItem; // don't forget UnloadFile
AThread: TThread): TFPCMsgFilePoolItem; virtual; // don't forget UnloadFile
function LoadFile(aFilename: string; UpdateFromDisk: boolean;
AThread: TThread): TFPCMsgFilePoolItem; // don't forget UnloadFile
procedure UnloadFile(var aFile: TFPCMsgFilePoolItem);
@ -214,6 +214,8 @@ type
function ReverseInstantFPCCacheDir(var aFilename: string; aSynchronized: boolean): boolean;
function ReverseTestBuildDir(MsgLine: TMessageLine; var aFilename: string): boolean;
function LongenFilename(MsgLine: TMessageLine; aFilename: string): string; // (worker thread)
protected
function GetDefaultPCFullVersion: LongWord; virtual;
public
DirectoryStack: TStrings;
MsgFilename: string; // e.g. /path/to/fpcsrc/compiler/msg/errore.msg
@ -223,7 +225,7 @@ type
InstantFPCCache: string; // with trailing pathdelim
TestBuildDir: string; // with trailing pathdelim
VirtualProjectFiles: TFilenameToPointerTree;
FPC_FullVersion: cardinal;
PC_FullVersion: LongWord;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Init; override; // called after macros resolved, before starting thread (main thread)
@ -247,6 +249,7 @@ type
class function GetFPCMsgPattern(Msg: TMessageLine): string; override;
class function GetFPCMsgValue1(Msg: TMessageLine): string; override;
class function GetFPCMsgValues(Msg: TMessageLine; out Value1, Value2: string): boolean; override;
class function MsgFilePool: TFPCMsgFilePool; virtual;
end;
var
@ -1072,9 +1075,9 @@ begin
FreeAndNil(fFileExists);
FreeAndNil(fCurSource);
if TranslationFile<>nil then
FPCMsgFilePool.UnloadFile(TranslationFile);
MsgFilePool.UnloadFile(TranslationFile);
if MsgFile<>nil then
FPCMsgFilePool.UnloadFile(MsgFile);
MsgFilePool.UnloadFile(MsgFile);
FreeAndNil(DirectoryStack);
FreeAndNil(fLineToMsgID);
inherited Destroy;
@ -1089,7 +1092,7 @@ procedure TIDEFPCParser.Init;
debugln(['WARNING: TFPCParser.Init missing msg file'])
else if (aFilename<>'') and (List=nil) then begin
try
List:=FPCMsgFilePool.LoadFile(aFilename,true,nil);
List:=MsgFilePool.LoadFile(aFilename,true,nil);
{$IFDEF VerboseExtToolThread}
debugln(['LoadMsgFile successfully read ',aFilename]);
{$ENDIF}
@ -1107,20 +1110,14 @@ var
p: PChar;
aTargetOS: String;
aTargetCPU: String;
FPCVersion: integer;
FPCRelease: integer;
FPCPatch: integer;
aProject: TLazProject;
aProjFile: TLazProjectFile;
begin
inherited Init;
// get FPC version
CodeToolBoss.GetFPCVersionForDirectory(Tool.WorkerDirectory, FPCVersion,
FPCRelease, FPCPatch);
FPC_FullVersion:=FPCVersion*10000+FPCRelease*100+FPCPatch;
PC_FullVersion:=GetDefaultPCFullVersion;
if FPCMsgFilePool<>nil then begin
if MsgFilePool<>nil then begin
aTargetOS:='';
aTargetCPU:='';
for i:=0 to Tool.Process.Parameters.Count-1 do begin
@ -1133,7 +1130,7 @@ begin
else if p[1]='P' then
aTargetCPU:=copy(Param,3,255);
end;
FPCMsgFilePool.GetMsgFileNames(Tool.Process.Executable,aTargetOS,aTargetCPU,
MsgFilePool.GetMsgFileNames(Tool.Process.Executable,aTargetOS,aTargetCPU,
MsgFilename,TranslationFilename);
end;
@ -1541,7 +1538,7 @@ end;
function TIDEFPCParser.CheckForInfos(p: PChar): boolean;
function ReadFPCLogo(PatternItem: PPatternToMsgID;
out FPCVersionAsInt: cardinal): boolean;
out FPCVersionAsInt: LongWord): boolean;
var
Line: string;
Ranges: TFPCMsgRanges;
@ -1580,7 +1577,7 @@ var
MsgLine: TMessageLine;
MsgType: TMessageLineUrgency;
PatternItem: PPatternToMsgID;
aFPCVersion: cardinal;
aFPCVersion: LongWord;
begin
Result:=false;
PatternItem:=fLineToMsgID.LineToPattern(p);
@ -1601,10 +1598,10 @@ begin
MsgLine.SubTool:=SubToolFPC;
MsgLine.Urgency:=MsgType;
if (fMsgID=FPCMsgIDLogo) and ReadFPCLogo(PatternItem,aFPCVersion) then begin
if aFPCVersion<>FPC_FullVersion then begin
if aFPCVersion<>PC_FullVersion then begin
// unexpected FPC version => always show
MsgLine.Urgency:=mluImportant;
FPC_FullVersion:=aFPCVersion;
PC_FullVersion:=aFPCVersion;
end;
end;
AddMsgLine(MsgLine);
@ -2589,7 +2586,7 @@ begin
FFilesToIgnoreUnitNotUsed:=TStringList.Create;
HideHintsSenderNotUsed:=true;
HideHintsUnitNotUsedInMainSource:=true;
FPC_FullVersion:=GetCompiledFPCVersion;
PC_FullVersion:=GetCompiledFPCVersion;
end;
function TIDEFPCParser.FileExists(const Filename: string; aSynchronized: boolean
@ -2897,7 +2894,7 @@ var
p: PChar;
begin
if Line='' then exit;
if FPC_FullVersion>=20701 then
if PC_FullVersion>=20701 then
Line:=ConsoleToUTF8(Line)
else begin
{$IFDEF MSWINDOWS}
@ -3063,6 +3060,12 @@ begin
MsgLine.Attribute[FPCMsgAttrWorkerDirectory]:=Tool.WorkerDirectory;
end;
function TIDEFPCParser.GetDefaultPCFullVersion: LongWord;
begin
// get FPC version
Result:=LongWord(CodeToolBoss.GetPCVersionForDirectory(Tool.WorkerDirectory));
end;
procedure TIDEFPCParser.ImproveMessages(aPhase: TExtToolParserSyncPhase);
var
i: Integer;
@ -3220,15 +3223,15 @@ var
MsgItem: TFPCMsgItem;
begin
Result:='';
if CompareText(SubTool,SubToolFPC)=0 then begin
CurMsgFile:=FPCMsgFilePool.LoadCurrentEnglishFile(false,nil);
if CompareText(SubTool,DefaultSubTool)=0 then begin
CurMsgFile:=MsgFilePool.LoadCurrentEnglishFile(false,nil);
if CurMsgFile=nil then exit;
try
MsgItem:=CurMsgFile.GetMsg(MsgID);
if MsgItem=nil then exit;
Result:=MsgItem.GetTrimmedComment(false,true);
finally
FPCMsgFilePool.UnloadFile(CurMsgFile);
MsgFilePool.UnloadFile(CurMsgFile);
end;
end;
end;
@ -3241,9 +3244,9 @@ var
begin
Result:='';
Urgency:=mluNone;
if CompareText(SubTool,SubToolFPC)=0 then begin
if FPCMsgFilePool=nil then exit;
CurMsgFile:=FPCMsgFilePool.LoadCurrentEnglishFile(false,nil);
if CompareText(SubTool,DefaultSubTool)=0 then begin
if MsgFilePool=nil then exit;
CurMsgFile:=MsgFilePool.LoadCurrentEnglishFile(false,nil);
if CurMsgFile=nil then exit;
try
MsgItem:=CurMsgFile.GetMsg(MsgID);
@ -3251,7 +3254,7 @@ begin
Result:=MsgItem.Pattern;
Urgency:=FPCMsgToMsgUrgency(MsgItem);
finally
FPCMsgFilePool.UnloadFile(CurMsgFile);
MsgFilePool.UnloadFile(CurMsgFile);
end;
end;
end;
@ -3284,7 +3287,7 @@ begin
Value1:='';
Value2:='';
if Msg=nil then exit(false);
if Msg.SubTool<>SubToolFPC then exit(false);
if Msg.SubTool<>DefaultSubTool then exit(false);
if (Msg.MsgID<>MsgId)
and (Msg.MsgID<>0) then exit(false);
Result:=true;
@ -3330,7 +3333,7 @@ class function TIDEFPCParser.GetFPCMsgValue1(Msg: TMessageLine): string;
begin
Result:='';
if Msg.MsgID<=0 then exit;
if Msg.SubTool<>SubToolFPC then exit;
if Msg.SubTool<>DefaultSubTool then exit;
if not etFPCMsgParser.GetFPCMsgValue1(Msg.Msg,GetFPCMsgPattern(Msg),Result) then
Result:='';
end;
@ -3340,14 +3343,19 @@ class function TIDEFPCParser.GetFPCMsgValues(Msg: TMessageLine; out Value1,
begin
Result:=false;
if Msg.MsgID<=0 then exit;
if Msg.SubTool<>SubToolFPC then exit;
if Msg.SubTool<>DefaultSubTool then exit;
Result:=etFPCMsgParser.GetFPCMsgValues2(Msg.Msg,GetFPCMsgPattern(Msg),Value1,Value2);
end;
class function TIDEFPCParser.MsgFilePool: TFPCMsgFilePool;
begin
Result:=FPCMsgFilePool;
end;
initialization
IDEFPCParser:=TIDEFPCParser;
finalization
FreeAndNil(FPCMsgFilePool)
FreeAndNil(FPCMsgFilePool);
end.

112
ide/etpas2jsmsgparser.pas Normal file
View File

@ -0,0 +1,112 @@
{
***************************************************************************
* *
* This source is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This code is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* A copy of the GNU General Public License is available on the World *
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
* obtain it by writing to the Free Software Foundation, *
* Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
* *
***************************************************************************
Author: Mattias Gaertner
Abstract:
Parser for Free Pascal Compiler output.
}
unit etPas2jsMsgParser;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils,
IDEExternToolIntf, LazFileUtils,
etFPCMsgParser, EnvironmentOpts;
type
{ TPas2jsMsgFilePool }
TPas2jsMsgFilePool = class(TFPCMsgFilePool)
public
function LoadCurrentEnglishFile(UpdateFromDisk: boolean; AThread: TThread
): TFPCMsgFilePoolItem; override;
procedure GetMsgFileNames({%H-}CompilerFilename, {%H-}TargetOS, {%H-}TargetCPU: string;
out anEnglishFile, aTranslationFile: string);
end;
{ TIDEPas2jsParser }
TIDEPas2jsParser = class(TIDEFPCParser)
public
class function CanParseSubTool(const SubTool: string): boolean; override;
class function DefaultSubTool: string; override;
class function Priority: integer; override;
class function MsgFilePool: TFPCMsgFilePool; override;
end;
var
Pas2jsMsgFilePool: TFPCMsgFilePool = nil;
implementation
{ TPas2jsMsgFilePool }
function TPas2jsMsgFilePool.LoadCurrentEnglishFile(UpdateFromDisk: boolean;
AThread: TThread): TFPCMsgFilePoolItem;
var
Filename: String;
begin
Result:=nil;
Filename:=AppendPathDelim(EnvironmentOptions.GetParsedLazarusDirectory)+'ide'+PathDelim+'pas2jsmsg.txt';
if not FilenameIsAbsolute(Filename) then exit;
Result:=LoadFile(Filename,UpdateFromDisk,AThread);
end;
procedure TPas2jsMsgFilePool.GetMsgFileNames(CompilerFilename, TargetOS,
TargetCPU: string; out anEnglishFile, aTranslationFile: string);
begin
anEnglishFile:=AppendPathDelim(EnvironmentOptions.GetParsedLazarusDirectory)+'ide'+PathDelim+'pas2jsmsg.txt';
aTranslationFile:='';
end;
{ TIDEPas2jsParser }
class function TIDEPas2jsParser.CanParseSubTool(const SubTool: string): boolean;
begin
Result:=(CompareText(SubTool,SubToolPas2js)=0);
end;
class function TIDEPas2jsParser.DefaultSubTool: string;
begin
Result:=SubToolPas2js;
end;
class function TIDEPas2jsParser.Priority: integer;
begin
Result:=SubToolPas2jsPriority;
end;
class function TIDEPas2jsParser.MsgFilePool: TFPCMsgFilePool;
begin
Result:=inherited MsgFilePool;
end;
initialization
IDEPas2jsParser:=TIDEPas2jsParser;
finalization
FreeAndNil(Pas2jsMsgFilePool);
end.

View File

@ -65,7 +65,7 @@
<PackageName Value="SynEdit"/>
</Item7>
</RequiredPackages>
<Units Count="242">
<Units Count="243">
<Unit0>
<Filename Value="lazarus.pp"/>
<IsPartOfProject Value="True"/>
@ -1258,6 +1258,7 @@
<Filename Value="searchresultview.pp"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
<UnitName Value="SearchResultView"/>
</Unit211>
<Unit212>
<Filename Value="invertassigntool.pas"/>
@ -1412,6 +1413,11 @@
<IsPartOfProject Value="True"/>
<UnitName Value="ProjectDescriptors"/>
</Unit241>
<Unit242>
<Filename Value="etpas2jsmsgparser.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="etPas2jsMsgParser"/>
</Unit242>
</Units>
</ProjectOptions>
<CompilerOptions>

43
ide/pas2jsmsg.txt Normal file
View File

@ -0,0 +1,43 @@
# pas2js messages used by the IDE in fpc msg format
#
# Author: Mattias Gaertner
#
# The constants are build in the following order:
# <part>_<type>_<txtidentifier>
#
# <part> is the part of the compiler the message is used
# asmr_ assembler parsing
# asmw_ assembler writing/binary writers
# unit_ unit handling
# option_ command line parameter parsing
# scan_ scanner
# parser_ parser
# type_ type checking
# general_ general info
# exec_ calls to assembler, external linker, binder
# link_ internal linker
# package_ package handling
#
# <type> the type of the message it should normally used for
# f_ fatal error
# e_ error
# w_ warning
# n_ note
# h_ hint
# i_ info
# l_ add linenumber
# u_ used
# t_ tried
# c_ conditional
# d_ debug message
# x_ executable informations
# o_ normal (e.g., "press enter to continue")
#
# <type> can contain a minus sign at the beginning to mark that
# the message is off by default. Look at type_w_explicit_string_cast
# for example.
parser_i_compiling=03104_I_Compiling $1 ...
% When you turn on information messages (\var{-vi}), the compiler tells you
% what units it is recompiling.