mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 16:09:31 +02:00
* reworked saving/restoring the scanner state (immediately replace scanner
with temporary one when saving, since it's also freed when restoring -> called replace_scanner() instead of save_scanner() now) * when using -vd, print out the text that is internally generated for injecting into the scanner git-svn-id: branches/jvmbackend@18442 -
This commit is contained in:
parent
698deb08c5
commit
009a30d8cf
@ -375,7 +375,7 @@ scanner_e_illegal_alignment_directive=02088_E_Illegal alignment directive
|
||||
#
|
||||
# Parser
|
||||
#
|
||||
# 03317 is the last used one
|
||||
# 03318 is the last used one
|
||||
#
|
||||
% \section{Parser messages}
|
||||
% This section lists all parser messages. The parser takes care of the
|
||||
@ -1416,6 +1416,10 @@ parser_e_java_no_inherited_constructor=03317_E_Constructors are not automaticall
|
||||
% For compatibility with external Java code, FPC does the same. If you require access to the same
|
||||
% constructors in a child class, define them in the child class and call the inherited one from
|
||||
% there.
|
||||
parser_d_internal_parser_string=03318_D_Parsing internally generated code: $1
|
||||
% The compiler sometimes internally constructs Pascal code that is subsequently
|
||||
% injected into the program. These messages display such code, in order to help
|
||||
% with debugging errors in them.
|
||||
% \end{description}
|
||||
# Type Checking
|
||||
#
|
||||
|
@ -409,6 +409,7 @@ const
|
||||
parser_e_final_only_external=03315;
|
||||
parser_e_no_typed_const=03316;
|
||||
parser_e_java_no_inherited_constructor=03317;
|
||||
parser_d_internal_parser_string=03318;
|
||||
type_e_mismatch=04000;
|
||||
type_e_incompatible_types=04001;
|
||||
type_e_not_equal_types=04002;
|
||||
@ -908,9 +909,9 @@ const
|
||||
option_info=11024;
|
||||
option_help_pages=11025;
|
||||
|
||||
MsgTxtSize = 61683;
|
||||
MsgTxtSize = 61729;
|
||||
|
||||
MsgIdxMax : array[1..20] of longint=(
|
||||
26,89,318,105,87,54,111,23,202,63,
|
||||
26,89,319,105,87,54,111,23,202,63,
|
||||
49,20,1,1,1,1,1,1,1,1
|
||||
);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,35 +27,9 @@ unit symcreat;
|
||||
interface
|
||||
|
||||
uses
|
||||
finput,
|
||||
finput,tokens,scanner,
|
||||
symconst,symdef,symbase;
|
||||
|
||||
{ in the JVM, constructors are not automatically inherited (so you can hide
|
||||
them). To emulate the Pascal behaviour, we have to automatically add
|
||||
all parent constructors to the current class as well. }
|
||||
procedure add_missing_parent_constructors_intf(obj: tobjectdef);
|
||||
procedure add_missing_parent_constructors_impl(obj: tobjectdef);
|
||||
|
||||
{ parses a (class or regular) method/constructor/destructor declaration from
|
||||
str, as if it were declared in astruct's declaration body }
|
||||
function str_parse_method_dec(str: ansistring; is_classdef: boolean; astruct: tabstractrecorddef; out pd: tprocdef): boolean;
|
||||
|
||||
{ parses a (class or regular) method/constructor/destructor implementation
|
||||
from str, as if it appeared in the current unit's implementation section }
|
||||
function str_parse_method_impl(str: ansistring; is_classdef: boolean):boolean;
|
||||
|
||||
{ goes through all defs in st to add implementations for synthetic methods
|
||||
added earlier }
|
||||
procedure add_synthetic_method_implementations(st: tsymtable);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
verbose,systems,
|
||||
tokens,scanner,
|
||||
symtype,symsym,symtable,
|
||||
pbase,pdecobj,psub,
|
||||
defcmp;
|
||||
|
||||
type
|
||||
tscannerstate = record
|
||||
@ -65,7 +39,44 @@ implementation
|
||||
valid: boolean;
|
||||
end;
|
||||
|
||||
procedure save_scanner(out sstate: tscannerstate);
|
||||
{ save/restore the scanner state before/after injecting }
|
||||
procedure replace_scanner(const tempname: string; out sstate: tscannerstate);
|
||||
procedure restore_scanner(const sstate: tscannerstate);
|
||||
|
||||
{ parses a (class or regular) method/constructor/destructor declaration from
|
||||
str, as if it were declared in astruct's declaration body
|
||||
|
||||
WARNING: save the scanner state before calling this routine, and restore
|
||||
when done. }
|
||||
function str_parse_method_dec(str: ansistring; is_classdef: boolean; astruct: tabstractrecorddef; out pd: tprocdef): boolean;
|
||||
|
||||
{ parses a (class or regular) method/constructor/destructor implementation
|
||||
from str, as if it appeared in the current unit's implementation section
|
||||
|
||||
WARNING: save the scanner state before calling this routine, and restore
|
||||
when done. }
|
||||
function str_parse_method_impl(str: ansistring; is_classdef: boolean):boolean;
|
||||
|
||||
|
||||
{ in the JVM, constructors are not automatically inherited (so you can hide
|
||||
them). To emulate the Pascal behaviour, we have to automatically add
|
||||
all parent constructors to the current class as well.}
|
||||
procedure add_missing_parent_constructors_intf(obj: tobjectdef);
|
||||
// procedure add_missing_parent_constructors_impl(obj: tobjectdef);
|
||||
|
||||
{ goes through all defs in st to add implementations for synthetic methods
|
||||
added earlier }
|
||||
procedure add_synthetic_method_implementations(st: tsymtable);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
verbose,systems,
|
||||
symtype,symsym,symtable,defutil,
|
||||
pbase,pdecobj,psub,
|
||||
defcmp;
|
||||
|
||||
procedure replace_scanner(const tempname: string; out sstate: tscannerstate);
|
||||
begin
|
||||
{ would require saving of idtoken, pattern etc }
|
||||
if (token=_ID) then
|
||||
@ -74,6 +85,7 @@ implementation
|
||||
sstate.old_token:=token;
|
||||
sstate.old_c:=c;
|
||||
sstate.valid:=true;
|
||||
current_scanner:=tscannerfile.Create('_Macro_.'+tempname);
|
||||
end;
|
||||
|
||||
|
||||
@ -93,6 +105,7 @@ implementation
|
||||
var
|
||||
oldparse_only: boolean;
|
||||
begin
|
||||
Message1(parser_d_internal_parser_string,str);
|
||||
oldparse_only:=parse_only;
|
||||
parse_only:=true;
|
||||
result:=false;
|
||||
@ -115,6 +128,7 @@ implementation
|
||||
var
|
||||
oldparse_only: boolean;
|
||||
begin
|
||||
Message1(parser_d_internal_parser_string,str);
|
||||
oldparse_only:=parse_only;
|
||||
parse_only:=false;
|
||||
result:=false;
|
||||
@ -174,10 +188,7 @@ implementation
|
||||
{ if we get here, we did not find it in the current objectdef ->
|
||||
add }
|
||||
if not sstate.valid then
|
||||
begin
|
||||
save_scanner(sstate);
|
||||
current_scanner:=tscannerfile.Create('_Macro_.parent_constructors_intf');
|
||||
end;
|
||||
replace_scanner('parent_constructors_intf',sstate);
|
||||
isclassmethod:=
|
||||
(po_classmethod in tprocdef(pd).procoptions) and
|
||||
not(tprocdef(pd).proctypeoption in [potype_constructor,potype_destructor]);
|
||||
@ -231,10 +242,7 @@ implementation
|
||||
not(oo_is_external in tobjectdef(def).objectoptions) then
|
||||
begin
|
||||
if not sstate.valid then
|
||||
begin
|
||||
save_scanner(sstate);
|
||||
current_scanner:=tscannerfile.Create('_Macro_.parent_constructors_impl');
|
||||
end;
|
||||
replace_scanner('synthetic_impl',sstate);
|
||||
add_missing_parent_constructors_impl(tobjectdef(def));
|
||||
end;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user