mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-20 13:29:14 +02:00
pas2js: typeinfo(specialization)
git-svn-id: trunk@44220 -
This commit is contained in:
parent
b802ee6450
commit
1bf392a726
@ -1173,12 +1173,13 @@ var
|
|||||||
C: TClass;
|
C: TClass;
|
||||||
Members, Args: TFPList;
|
Members, Args: TFPList;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
Member: TPasElement;
|
Member, Param: TPasElement;
|
||||||
MemberResolved: TPasResolverResult;
|
MemberResolved: TPasResolverResult;
|
||||||
Prop: TPasProperty;
|
Prop: TPasProperty;
|
||||||
ProcType: TPasProcedureType;
|
ProcType: TPasProcedureType;
|
||||||
ClassEl: TPasClassType;
|
ClassEl: TPasClassType;
|
||||||
ArrType: TPasArrayType;
|
ArrType: TPasArrayType;
|
||||||
|
SpecType: TPasSpecializeType;
|
||||||
begin
|
begin
|
||||||
{$IFDEF VerbosePasAnalyzer}
|
{$IFDEF VerbosePasAnalyzer}
|
||||||
writeln('TPasAnalyzer.UsePublished START ',GetObjName(El));
|
writeln('TPasAnalyzer.UsePublished START ',GetObjName(El));
|
||||||
@ -1270,7 +1271,18 @@ begin
|
|||||||
UseSubEl(TPasFunctionType(El).ResultEl.ResultType);
|
UseSubEl(TPasFunctionType(El).ResultEl.ResultType);
|
||||||
end
|
end
|
||||||
else if C=TPasSpecializeType then
|
else if C=TPasSpecializeType then
|
||||||
UseSubEl(TPasSpecializeType(El).DestType)
|
begin
|
||||||
|
SpecType:=TPasSpecializeType(El);
|
||||||
|
// SpecType.DestType is the generic type, which is never used
|
||||||
|
if SpecType.CustomData is TPasSpecializeTypeData then
|
||||||
|
UseSubEl(TPasSpecializeTypeData(El.CustomData).SpecializedType);
|
||||||
|
for i:=0 to SpecType.Params.Count-1 do
|
||||||
|
begin
|
||||||
|
Param:=TPasElement(SpecType.Params[i]);
|
||||||
|
if Param is TPasGenericTemplateType then continue;
|
||||||
|
UseSubEl(Param);
|
||||||
|
end;
|
||||||
|
end
|
||||||
else if C=TPasGenericTemplateType then
|
else if C=TPasGenericTemplateType then
|
||||||
begin
|
begin
|
||||||
if ScopeModule=nil then
|
if ScopeModule=nil then
|
||||||
@ -2385,7 +2397,7 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
if not MarkElementAsUsed(El) then exit;
|
if not MarkElementAsUsed(El) then exit;
|
||||||
// El.DestType is TPasGenericType, which is never be used
|
// El.DestType is the generic type, which is never used
|
||||||
if El.CustomData is TPasSpecializeTypeData then
|
if El.CustomData is TPasSpecializeTypeData then
|
||||||
UseElType(El,TPasSpecializeTypeData(El.CustomData).SpecializedType,Mode);
|
UseElType(El,TPasSpecializeTypeData(El.CustomData).SpecializedType,Mode);
|
||||||
for i:=0 to El.Params.Count-1 do
|
for i:=0 to El.Params.Count-1 do
|
||||||
@ -2690,7 +2702,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
// declaration was never used
|
// declaration was never used
|
||||||
if IsSpecializedGenericType(Decl) then
|
if IsSpecializedGenericType(Decl) then
|
||||||
continue;
|
continue; // no hints for not used specializations
|
||||||
EmitMessage(20170311231734,mtHint,nPALocalXYNotUsed,
|
EmitMessage(20170311231734,mtHint,nPALocalXYNotUsed,
|
||||||
sPALocalXYNotUsed,[Decl.ElementTypeName,Decl.Name],Decl);
|
sPALocalXYNotUsed,[Decl.ElementTypeName,Decl.Name],Decl);
|
||||||
end;
|
end;
|
||||||
@ -2726,7 +2738,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
SpecEl:=TPRSpecializedItem(SpecializedItems[i]).SpecializedEl;
|
SpecEl:=TPRSpecializedItem(SpecializedItems[i]).SpecializedEl;
|
||||||
if FindElement(SpecEl)<>nil then
|
if FindElement(SpecEl)<>nil then
|
||||||
exit; // a specialization of this generic type is used
|
exit; // a specialization of this generic type is used -> the generic is used
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2832,7 +2844,7 @@ begin
|
|||||||
ImplProc:=ProcScope.ImplProc;
|
ImplProc:=ProcScope.ImplProc;
|
||||||
if (ProcScope.ClassRecScope<>nil)
|
if (ProcScope.ClassRecScope<>nil)
|
||||||
and (ProcScope.ClassRecScope.SpecializedFromItem<>nil) then
|
and (ProcScope.ClassRecScope.SpecializedFromItem<>nil) then
|
||||||
exit; // specialized proc
|
exit; // no hints for not used specializations
|
||||||
|
|
||||||
if not PAElementExists(DeclProc) then
|
if not PAElementExists(DeclProc) then
|
||||||
begin
|
begin
|
||||||
|
@ -159,6 +159,7 @@ type
|
|||||||
procedure TestWP_TypeInfo;
|
procedure TestWP_TypeInfo;
|
||||||
procedure TestWP_TypeInfo_PropertyEnumType;
|
procedure TestWP_TypeInfo_PropertyEnumType;
|
||||||
procedure TestWP_TypeInfo_Alias;
|
procedure TestWP_TypeInfo_Alias;
|
||||||
|
procedure TestWP_TypeInfo_Specialize;
|
||||||
procedure TestWP_ForInClass;
|
procedure TestWP_ForInClass;
|
||||||
procedure TestWP_AssertSysUtils;
|
procedure TestWP_AssertSysUtils;
|
||||||
procedure TestWP_RangeErrorSysUtils;
|
procedure TestWP_RangeErrorSysUtils;
|
||||||
@ -2825,6 +2826,30 @@ begin
|
|||||||
AnalyzeWholeProgram;
|
AnalyzeWholeProgram;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestUseAnalyzer.TestWP_TypeInfo_Specialize;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'type',
|
||||||
|
' TObject = class end;',
|
||||||
|
' generic TProc<T> = procedure(a: T) of object;',
|
||||||
|
' TWordProc = specialize TProc<word>;',
|
||||||
|
' {$M+}',
|
||||||
|
' TPersistent = class',
|
||||||
|
' private',
|
||||||
|
' FWordProc: TWordProc;',
|
||||||
|
' published',
|
||||||
|
' property Proc: TWordProc read FWordProc write FWordProc;',
|
||||||
|
' end;',
|
||||||
|
' {$M-}',
|
||||||
|
'var',
|
||||||
|
' {#p_notypeinfo}p: pointer;',
|
||||||
|
'begin',
|
||||||
|
' p:=typeinfo(TPersistent);',
|
||||||
|
'']);
|
||||||
|
AnalyzeWholeProgram;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestUseAnalyzer.TestWP_ForInClass;
|
procedure TTestUseAnalyzer.TestWP_ForInClass;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
|
@ -23879,6 +23879,16 @@ begin
|
|||||||
El:=ResolveSimpleAliasType(El);
|
El:=ResolveSimpleAliasType(El);
|
||||||
if El=nil then
|
if El=nil then
|
||||||
RaiseInconsistency(20170409172756,El);
|
RaiseInconsistency(20170409172756,El);
|
||||||
|
C:=El.ClassType;
|
||||||
|
|
||||||
|
if C=TPasSpecializeType then
|
||||||
|
begin
|
||||||
|
if not (El.CustomData is TPasSpecializeTypeData) then
|
||||||
|
RaiseInconsistency(20200220113319,El);
|
||||||
|
El:=TPasSpecializeTypeData(El.CustomData).SpecializedType;
|
||||||
|
C:=El.ClassType;
|
||||||
|
end;
|
||||||
|
|
||||||
if (El=AContext.PasElement) and not Full then
|
if (El=AContext.PasElement) and not Full then
|
||||||
begin
|
begin
|
||||||
// referring to itself
|
// referring to itself
|
||||||
@ -23891,7 +23901,6 @@ begin
|
|||||||
else
|
else
|
||||||
RaiseNotSupported(ErrorEl,AContext,20170905150746,'cannot typeinfo itself');
|
RaiseNotSupported(ErrorEl,AContext,20170905150746,'cannot typeinfo itself');
|
||||||
end;
|
end;
|
||||||
C:=El.ClassType;
|
|
||||||
if C=TPasUnresolvedSymbolRef then
|
if C=TPasUnresolvedSymbolRef then
|
||||||
begin
|
begin
|
||||||
if El.Name='' then
|
if El.Name='' then
|
||||||
|
@ -41,6 +41,7 @@ type
|
|||||||
procedure TestGen_ExtClass_Array;
|
procedure TestGen_ExtClass_Array;
|
||||||
procedure TestGen_ExtClass_GenJSValueAssign;
|
procedure TestGen_ExtClass_GenJSValueAssign;
|
||||||
procedure TestGen_ExtClass_AliasMemberType;
|
procedure TestGen_ExtClass_AliasMemberType;
|
||||||
|
Procedure TestGen_ExtClass_RTTI;
|
||||||
|
|
||||||
// statements
|
// statements
|
||||||
Procedure TestGen_InlineSpec_Constructor;
|
Procedure TestGen_InlineSpec_Constructor;
|
||||||
@ -844,6 +845,39 @@ begin
|
|||||||
'']));
|
'']));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestGenerics.TestGen_ExtClass_RTTI;
|
||||||
|
begin
|
||||||
|
Converter.Options:=Converter.Options-[coNoTypeInfo];
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'{$mode objfpc}',
|
||||||
|
'{$modeswitch externalclass}',
|
||||||
|
'type',
|
||||||
|
' generic TGJSSET<T> = class external name ''SET''',
|
||||||
|
' A: T;',
|
||||||
|
' end;',
|
||||||
|
' TJSSet = specialize TGJSSET<JSValue>;',
|
||||||
|
' TJSSetEventProc = reference to procedure(value : JSValue; key: NativeInt; set_: TJSSet);',
|
||||||
|
'var p: Pointer;',
|
||||||
|
'begin',
|
||||||
|
' p:=typeinfo(TJSSetEventProc);',
|
||||||
|
'']);
|
||||||
|
ConvertProgram;
|
||||||
|
CheckSource('TestGen_ExtClass_RTTI',
|
||||||
|
LinesToStr([ // statements
|
||||||
|
'$mod.$rtti.$ExtClass("TGJSSET$G1", {',
|
||||||
|
' jsclass: "SET"',
|
||||||
|
'});',
|
||||||
|
'$mod.$rtti.$RefToProcVar("TJSSetEventProc", {',
|
||||||
|
' procsig: rtl.newTIProcSig([["value", rtl.jsvalue], ["key", rtl.nativeint], ["set_", $mod.$rtti["TGJSSET$G1"]]])',
|
||||||
|
'});',
|
||||||
|
'this.p = null;',
|
||||||
|
'']),
|
||||||
|
LinesToStr([ // $mod.$main
|
||||||
|
'$mod.p = $mod.$rtti["TJSSetEventProc"];',
|
||||||
|
'']));
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestGenerics.TestGen_InlineSpec_Constructor;
|
procedure TTestGenerics.TestGen_InlineSpec_Constructor;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user