mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-19 10:29:18 +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
|
# Parser
|
||||||
#
|
#
|
||||||
# 03317 is the last used one
|
# 03318 is the last used one
|
||||||
#
|
#
|
||||||
% \section{Parser messages}
|
% \section{Parser messages}
|
||||||
% This section lists all parser messages. The parser takes care of the
|
% 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
|
% 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
|
% constructors in a child class, define them in the child class and call the inherited one from
|
||||||
% there.
|
% 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}
|
% \end{description}
|
||||||
# Type Checking
|
# Type Checking
|
||||||
#
|
#
|
||||||
|
@ -409,6 +409,7 @@ const
|
|||||||
parser_e_final_only_external=03315;
|
parser_e_final_only_external=03315;
|
||||||
parser_e_no_typed_const=03316;
|
parser_e_no_typed_const=03316;
|
||||||
parser_e_java_no_inherited_constructor=03317;
|
parser_e_java_no_inherited_constructor=03317;
|
||||||
|
parser_d_internal_parser_string=03318;
|
||||||
type_e_mismatch=04000;
|
type_e_mismatch=04000;
|
||||||
type_e_incompatible_types=04001;
|
type_e_incompatible_types=04001;
|
||||||
type_e_not_equal_types=04002;
|
type_e_not_equal_types=04002;
|
||||||
@ -908,9 +909,9 @@ const
|
|||||||
option_info=11024;
|
option_info=11024;
|
||||||
option_help_pages=11025;
|
option_help_pages=11025;
|
||||||
|
|
||||||
MsgTxtSize = 61683;
|
MsgTxtSize = 61729;
|
||||||
|
|
||||||
MsgIdxMax : array[1..20] of longint=(
|
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
|
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
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
finput,
|
finput,tokens,scanner,
|
||||||
symconst,symdef,symbase;
|
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
|
type
|
||||||
tscannerstate = record
|
tscannerstate = record
|
||||||
@ -65,7 +39,44 @@ implementation
|
|||||||
valid: boolean;
|
valid: boolean;
|
||||||
end;
|
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
|
begin
|
||||||
{ would require saving of idtoken, pattern etc }
|
{ would require saving of idtoken, pattern etc }
|
||||||
if (token=_ID) then
|
if (token=_ID) then
|
||||||
@ -74,6 +85,7 @@ implementation
|
|||||||
sstate.old_token:=token;
|
sstate.old_token:=token;
|
||||||
sstate.old_c:=c;
|
sstate.old_c:=c;
|
||||||
sstate.valid:=true;
|
sstate.valid:=true;
|
||||||
|
current_scanner:=tscannerfile.Create('_Macro_.'+tempname);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -93,6 +105,7 @@ implementation
|
|||||||
var
|
var
|
||||||
oldparse_only: boolean;
|
oldparse_only: boolean;
|
||||||
begin
|
begin
|
||||||
|
Message1(parser_d_internal_parser_string,str);
|
||||||
oldparse_only:=parse_only;
|
oldparse_only:=parse_only;
|
||||||
parse_only:=true;
|
parse_only:=true;
|
||||||
result:=false;
|
result:=false;
|
||||||
@ -115,6 +128,7 @@ implementation
|
|||||||
var
|
var
|
||||||
oldparse_only: boolean;
|
oldparse_only: boolean;
|
||||||
begin
|
begin
|
||||||
|
Message1(parser_d_internal_parser_string,str);
|
||||||
oldparse_only:=parse_only;
|
oldparse_only:=parse_only;
|
||||||
parse_only:=false;
|
parse_only:=false;
|
||||||
result:=false;
|
result:=false;
|
||||||
@ -174,10 +188,7 @@ implementation
|
|||||||
{ if we get here, we did not find it in the current objectdef ->
|
{ if we get here, we did not find it in the current objectdef ->
|
||||||
add }
|
add }
|
||||||
if not sstate.valid then
|
if not sstate.valid then
|
||||||
begin
|
replace_scanner('parent_constructors_intf',sstate);
|
||||||
save_scanner(sstate);
|
|
||||||
current_scanner:=tscannerfile.Create('_Macro_.parent_constructors_intf');
|
|
||||||
end;
|
|
||||||
isclassmethod:=
|
isclassmethod:=
|
||||||
(po_classmethod in tprocdef(pd).procoptions) and
|
(po_classmethod in tprocdef(pd).procoptions) and
|
||||||
not(tprocdef(pd).proctypeoption in [potype_constructor,potype_destructor]);
|
not(tprocdef(pd).proctypeoption in [potype_constructor,potype_destructor]);
|
||||||
@ -231,10 +242,7 @@ implementation
|
|||||||
not(oo_is_external in tobjectdef(def).objectoptions) then
|
not(oo_is_external in tobjectdef(def).objectoptions) then
|
||||||
begin
|
begin
|
||||||
if not sstate.valid then
|
if not sstate.valid then
|
||||||
begin
|
replace_scanner('synthetic_impl',sstate);
|
||||||
save_scanner(sstate);
|
|
||||||
current_scanner:=tscannerfile.Create('_Macro_.parent_constructors_impl');
|
|
||||||
end;
|
|
||||||
add_missing_parent_constructors_impl(tobjectdef(def));
|
add_missing_parent_constructors_impl(tobjectdef(def));
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user