mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-20 14:09:12 +02:00
fcl-passrc: specialize inlinespecializeexpr
git-svn-id: trunk@42702 -
This commit is contained in:
parent
0e79bd2c70
commit
32573139a8
@ -1584,6 +1584,7 @@ type
|
|||||||
procedure ResolveSetParamsExpr(Params: TParamsExpr); virtual;
|
procedure ResolveSetParamsExpr(Params: TParamsExpr); virtual;
|
||||||
procedure ResolveArrayValues(El: TArrayValues); virtual;
|
procedure ResolveArrayValues(El: TArrayValues); virtual;
|
||||||
procedure ResolveRecordValues(El: TRecordValues); virtual;
|
procedure ResolveRecordValues(El: TRecordValues); virtual;
|
||||||
|
procedure ResolveInlineSpecializeExpr(El: TInlineSpecializeExpr); virtual;
|
||||||
function ResolveAccessor(Expr: TPasExpr): TPasElement;
|
function ResolveAccessor(Expr: TPasExpr): TPasElement;
|
||||||
procedure SetResolvedRefAccess(Expr: TPasExpr; Ref: TResolvedReference;
|
procedure SetResolvedRefAccess(Expr: TPasExpr; Ref: TResolvedReference;
|
||||||
Access: TResolvedRefAccess); virtual;
|
Access: TResolvedRefAccess); virtual;
|
||||||
@ -6312,13 +6313,16 @@ var
|
|||||||
Params, GenericTemplateList: TFPList;
|
Params, GenericTemplateList: TFPList;
|
||||||
P: TPasElement;
|
P: TPasElement;
|
||||||
DestType: TPasType;
|
DestType: TPasType;
|
||||||
i: Integer;
|
i, ScopeDepth: Integer;
|
||||||
begin
|
begin
|
||||||
{$IFDEF VerbosePasResolver}
|
{$IFDEF VerbosePasResolver}
|
||||||
//writeln('TPasResolver.FinishSpecializeType ');
|
//writeln('TPasResolver.FinishSpecializeType ');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
// resolve Params
|
// resolve Params
|
||||||
|
ScopeDepth:=StashSubExprScopes;
|
||||||
Params:=El.Params;
|
Params:=El.Params;
|
||||||
|
if Params.Count=0 then
|
||||||
|
RaiseMsg(20190724114416,nMissingParameterX,sMissingParameterX,['type'],El);
|
||||||
for i:=0 to Params.Count-1 do
|
for i:=0 to Params.Count-1 do
|
||||||
begin
|
begin
|
||||||
P:=TPasElement(Params[i]);
|
P:=TPasElement(Params[i]);
|
||||||
@ -6328,11 +6332,9 @@ begin
|
|||||||
else
|
else
|
||||||
RaiseMsg(20190728113336,nXExpectedButYFound,sXExpectedButYFound,['type identifier',GetObjName(P)+' parameter '+IntToStr(i+1)],El);
|
RaiseMsg(20190728113336,nXExpectedButYFound,sXExpectedButYFound,['type identifier',GetObjName(P)+' parameter '+IntToStr(i+1)],El);
|
||||||
end;
|
end;
|
||||||
if Params.Count=0 then
|
RestoreStashedScopes(ScopeDepth);
|
||||||
RaiseMsg(20190724114416,nMissingParameterX,sMissingParameterX,['type'],El);
|
|
||||||
|
|
||||||
// check DestType
|
// check DestType
|
||||||
GenericTemplateList:=nil;
|
|
||||||
DestType:=El.DestType;
|
DestType:=El.DestType;
|
||||||
if DestType=nil then
|
if DestType=nil then
|
||||||
RaiseMsg(20190725184734,nIdentifierNotFound,sIdentifierNotFound,['specialize type'],El)
|
RaiseMsg(20190725184734,nIdentifierNotFound,sIdentifierNotFound,['specialize type'],El)
|
||||||
@ -9428,6 +9430,8 @@ begin
|
|||||||
end
|
end
|
||||||
else if ElClass=TProcedureExpr then
|
else if ElClass=TProcedureExpr then
|
||||||
// resolved by FinishScope(stProcedure)
|
// resolved by FinishScope(stProcedure)
|
||||||
|
else if ElClass=TInlineSpecializeExpr then
|
||||||
|
ResolveInlineSpecializeExpr(TInlineSpecializeExpr(El))
|
||||||
else
|
else
|
||||||
RaiseNotYetImplemented(20170222184329,El);
|
RaiseNotYetImplemented(20170222184329,El);
|
||||||
|
|
||||||
@ -10640,6 +10644,33 @@ begin
|
|||||||
LogMsg(20180429121127,mtHint,nMissingFieldsX,sMissingFieldsX,[s],El);
|
LogMsg(20180429121127,mtHint,nMissingFieldsX,sMissingFieldsX,[s],El);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPasResolver.ResolveInlineSpecializeExpr(El: TInlineSpecializeExpr);
|
||||||
|
var
|
||||||
|
aName: String;
|
||||||
|
SpecType: TPasSpecializeType;
|
||||||
|
Expr: TPasExpr;
|
||||||
|
GenType: TPasGenericType;
|
||||||
|
begin
|
||||||
|
SpecType:=El.DestType;
|
||||||
|
if SpecType.DestType<>nil then
|
||||||
|
RaiseNotYetImplemented(20190815092327,El,GetObjName(SpecType.DestType));
|
||||||
|
|
||||||
|
// resolve DestType
|
||||||
|
Expr:=SpecType.Expr;
|
||||||
|
if Expr=nil then
|
||||||
|
RaiseNotYetImplemented(20190815091319,SpecType);
|
||||||
|
if Expr.Kind<>pekIdent then
|
||||||
|
RaiseNotYetImplemented(20190815083349,Expr);
|
||||||
|
aName:=TPrimitiveExpr(Expr).Value;
|
||||||
|
GenType:=FindGenericType(aName,SpecType.Params.Count,Expr);
|
||||||
|
if GenType=nil then
|
||||||
|
RaiseMsg(20190815083433,nIdentifierNotFound,sIdentifierNotFound,[aName],Expr);
|
||||||
|
SpecType.DestType:=GenType;
|
||||||
|
GenType.AddRef{$IFDEF CheckPasTreeRefCount}('TPasAliasType.DestType'){$ENDIF};
|
||||||
|
|
||||||
|
FinishSpecializeType(SpecType);
|
||||||
|
end;
|
||||||
|
|
||||||
function TPasResolver.ResolveAccessor(Expr: TPasExpr): TPasElement;
|
function TPasResolver.ResolveAccessor(Expr: TPasExpr): TPasElement;
|
||||||
|
|
||||||
function SubResolvePrimitive(Prim: TPrimitiveExpr): TPasElement;
|
function SubResolvePrimitive(Prim: TPrimitiveExpr): TPasElement;
|
||||||
@ -15879,11 +15910,19 @@ end;
|
|||||||
|
|
||||||
procedure TPasResolver.SpecializeInlineSpecializeExpr(GenEl,
|
procedure TPasResolver.SpecializeInlineSpecializeExpr(GenEl,
|
||||||
SpecEl: TInlineSpecializeExpr);
|
SpecEl: TInlineSpecializeExpr);
|
||||||
|
var
|
||||||
|
GenSpec, SpecSpec: TPasSpecializeType;
|
||||||
begin
|
begin
|
||||||
SpecializeExpr(GenEl,SpecEl);
|
SpecializeExpr(GenEl,SpecEl);
|
||||||
SpecializeElExpr(GenEl,SpecEl,GenEl.NameExpr,SpecEl.NameExpr);
|
GenSpec:=GenEl.DestType;
|
||||||
SpecializeElList(GenEl,SpecEl,GenEl.Params,SpecEl.Params,true
|
SpecSpec:=TPasSpecializeType.Create('',SpecEl);
|
||||||
{$IFDEF CheckPasTreeRefCount},'TInlineSpecializeExpr.Params'{$ENDIF});
|
SpecEl.DestType:=SpecSpec;
|
||||||
|
|
||||||
|
SpecializeElExpr(GenSpec,SpecSpec,GenSpec.Expr,SpecSpec.Expr);
|
||||||
|
SpecializeElList(GenSpec,SpecSpec,GenSpec.Params,SpecSpec.Params,true
|
||||||
|
{$IFDEF CheckPasTreeRefCount},'TPasSpecializeType.Params'{$ENDIF});
|
||||||
|
|
||||||
|
// SpecSpec.DestType is done in ResolveInlineSpecializeExpr
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPasResolver.SpecializeProcedureExpr(GenEl, SpecEl: TProcedureExpr);
|
procedure TPasResolver.SpecializeProcedureExpr(GenEl, SpecEl: TProcedureExpr);
|
||||||
@ -24227,6 +24266,22 @@ procedure TPasResolver.ComputeElement(El: TPasElement; out
|
|||||||
Include(ResolvedEl.Flags,rrfCanBeStatement);
|
Include(ResolvedEl.Flags,rrfCanBeStatement);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure ComputeSpecializeType(SpecType: TPasSpecializeType);
|
||||||
|
var
|
||||||
|
TypeEl: TPasType;
|
||||||
|
begin
|
||||||
|
if SpecType.CustomData is TPasSpecializeTypeData then
|
||||||
|
begin
|
||||||
|
TypeEl:=TPasSpecializeTypeData(SpecType.CustomData).SpecializedType;
|
||||||
|
SetResolverIdentifier(ResolvedEl,btContext,TypeEl,TypeEl,TypeEl,[]);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
TypeEl:=SpecType.DestType;
|
||||||
|
SetResolverIdentifier(ResolvedEl,btContext,SpecType,TypeEl,SpecType,[]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
DeclEl: TPasElement;
|
DeclEl: TPasElement;
|
||||||
ElClass: TClass;
|
ElClass: TClass;
|
||||||
@ -24608,18 +24663,9 @@ begin
|
|||||||
SetResolverIdentifier(ResolvedEl,btContext,El,TPasGenericTemplateType(El),
|
SetResolverIdentifier(ResolvedEl,btContext,El,TPasGenericTemplateType(El),
|
||||||
TPasGenericTemplateType(El),[])
|
TPasGenericTemplateType(El),[])
|
||||||
else if ElClass=TPasSpecializeType then
|
else if ElClass=TPasSpecializeType then
|
||||||
begin
|
ComputeSpecializeType(TPasSpecializeType(El))
|
||||||
if El.CustomData is TPasSpecializeTypeData then
|
else if ElClass=TInlineSpecializeExpr then
|
||||||
begin
|
ComputeSpecializeType(TInlineSpecializeExpr(El).DestType)
|
||||||
TypeEl:=TPasSpecializeTypeData(El.CustomData).SpecializedType;
|
|
||||||
SetResolverIdentifier(ResolvedEl,btContext,TypeEl,TypeEl,TypeEl,[]);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
TypeEl:=TPasSpecializeType(El).DestType;
|
|
||||||
SetResolverIdentifier(ResolvedEl,btContext,El,TypeEl,TPasType(El),[]);
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
RaiseNotYetImplemented(20160922163705,El);
|
RaiseNotYetImplemented(20160922163705,El);
|
||||||
{$IF defined(nodejs) and defined(VerbosePasResolver)}
|
{$IF defined(nodejs) and defined(VerbosePasResolver)}
|
||||||
|
@ -604,10 +604,8 @@ type
|
|||||||
function GetDeclaration(full : Boolean): string; override;
|
function GetDeclaration(full : Boolean): string; override;
|
||||||
procedure ForEachCall(const aMethodCall: TOnForEachPasElement;
|
procedure ForEachCall(const aMethodCall: TOnForEachPasElement;
|
||||||
const Arg: Pointer); override;
|
const Arg: Pointer); override;
|
||||||
procedure AddParam(El: TPasElement);
|
|
||||||
public
|
public
|
||||||
NameExpr: TPasExpr; // TPrimitiveExpr
|
DestType: TPasSpecializeType;
|
||||||
Params: TFPList; // list of TPasType or TPasExpr
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TPasClassOfType }
|
{ TPasClassOfType }
|
||||||
@ -2034,17 +2032,11 @@ constructor TInlineSpecializeExpr.Create(const AName: string;
|
|||||||
begin
|
begin
|
||||||
if AName='' then ;
|
if AName='' then ;
|
||||||
inherited Create(AParent, pekSpecialize, eopNone);
|
inherited Create(AParent, pekSpecialize, eopNone);
|
||||||
Params:=TFPList.Create;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TInlineSpecializeExpr.Destroy;
|
destructor TInlineSpecializeExpr.Destroy;
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
ReleaseAndNil(TPasElement(NameExpr){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
|
ReleaseAndNil(TPasElement(DestType){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
|
||||||
for i:=0 to Params.Count-1 do
|
|
||||||
TPasElement(Params[i]).Release{$IFDEF CheckPasTreeRefCount}('TInlineSpecializeExpr.Params'){$ENDIF};
|
|
||||||
FreeAndNil(Params);
|
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2054,34 +2046,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TInlineSpecializeExpr.GetDeclaration(full: Boolean): string;
|
function TInlineSpecializeExpr.GetDeclaration(full: Boolean): string;
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
Result:='specialize ';
|
Result:=DestType.GetDeclaration(full);
|
||||||
Result:=Result+NameExpr.GetDeclaration(full);
|
|
||||||
Result:=Result+'<';
|
|
||||||
for i:=0 to Params.Count-1 do
|
|
||||||
begin
|
|
||||||
if i>0 then
|
|
||||||
Result:=Result+',';
|
|
||||||
Result:=Result+TPasElement(Params[i]).GetDeclaration(false);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TInlineSpecializeExpr.ForEachCall(
|
procedure TInlineSpecializeExpr.ForEachCall(
|
||||||
const aMethodCall: TOnForEachPasElement; const Arg: Pointer);
|
const aMethodCall: TOnForEachPasElement; const Arg: Pointer);
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
inherited ForEachCall(aMethodCall, Arg);
|
inherited ForEachCall(aMethodCall, Arg);
|
||||||
ForEachChildCall(aMethodCall,Arg,NameExpr,false);
|
ForEachChildCall(aMethodCall,Arg,DestType,false);
|
||||||
for i:=0 to Params.Count-1 do
|
|
||||||
ForEachChildCall(aMethodCall,Arg,TPasElement(Params[i]),true);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TInlineSpecializeExpr.AddParam(El: TPasElement);
|
|
||||||
begin
|
|
||||||
Params.Add(El);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TPasSpecializeType }
|
{ TPasSpecializeType }
|
||||||
@ -2119,7 +2092,7 @@ begin
|
|||||||
Result:=Result+',';
|
Result:=Result+',';
|
||||||
Result:=Result+TPasElement(Params[i]).GetDeclaration(false);
|
Result:=Result+TPasElement(Params[i]).GetDeclaration(false);
|
||||||
end;
|
end;
|
||||||
If Full then
|
If Full and (Name<>'') then
|
||||||
begin
|
begin
|
||||||
Result:=Name+' = '+Result;
|
Result:=Name+' = '+Result;
|
||||||
ProcessHints(False,Result);
|
ProcessHints(False,Result);
|
||||||
|
@ -321,7 +321,7 @@ type
|
|||||||
procedure ParseClassMembers(AType: TPasClassType);
|
procedure ParseClassMembers(AType: TPasClassType);
|
||||||
procedure ProcessMethod(AType: TPasClassType; IsClass : Boolean; AVisibility : TPasMemberVisibility);
|
procedure ProcessMethod(AType: TPasClassType; IsClass : Boolean; AVisibility : TPasMemberVisibility);
|
||||||
procedure ReadGenericArguments(List : TFPList;Parent : TPasElement);
|
procedure ReadGenericArguments(List : TFPList;Parent : TPasElement);
|
||||||
procedure ReadSpecializeArguments(Spec: TPasElement);
|
procedure ReadSpecializeArguments(Spec: TPasSpecializeType);
|
||||||
function ReadDottedIdentifier(Parent: TPasElement; out Expr: TPasExpr; NeedAsString: boolean): String;
|
function ReadDottedIdentifier(Parent: TPasElement; out Expr: TPasExpr; NeedAsString: boolean): String;
|
||||||
function CheckProcedureArgs(Parent: TPasElement;
|
function CheckProcedureArgs(Parent: TPasElement;
|
||||||
Args: TFPList; // list of TPasArgument
|
Args: TFPList; // list of TPasArgument
|
||||||
@ -2304,6 +2304,7 @@ var
|
|||||||
SrcPos, ScrPos: TPasSourcePos;
|
SrcPos, ScrPos: TPasSourcePos;
|
||||||
ProcType: TProcType;
|
ProcType: TProcType;
|
||||||
ProcExpr: TProcedureExpr;
|
ProcExpr: TProcedureExpr;
|
||||||
|
SpecType: TPasSpecializeType;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=nil;
|
Result:=nil;
|
||||||
@ -2389,7 +2390,8 @@ begin
|
|||||||
UngetToken;
|
UngetToken;
|
||||||
ParseExcExpectedIdentifier;
|
ParseExcExpectedIdentifier;
|
||||||
end;
|
end;
|
||||||
Last:=CreatePrimitiveExpr(AParent,pekString, '^'+CurTokenText);
|
Result:=CreatePrimitiveExpr(AParent,pekString, '^'+CurTokenText);
|
||||||
|
exit;
|
||||||
end;
|
end;
|
||||||
tkBraceOpen:
|
tkBraceOpen:
|
||||||
begin
|
begin
|
||||||
@ -2469,10 +2471,36 @@ begin
|
|||||||
break
|
break
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
// an inline specialization (e.g. A<B,C>)
|
// an inline specialization (e.g. A<B,C> or something.A<B>)
|
||||||
|
// check expression in front is an identifier
|
||||||
|
Expr:=Result;
|
||||||
|
while Expr.Kind=pekBinary do
|
||||||
|
begin
|
||||||
|
if Expr.OpCode<>eopSubIdent then
|
||||||
|
ParseExcSyntaxError;
|
||||||
|
Expr:=TBinaryExpr(Expr).right;
|
||||||
|
end;
|
||||||
|
if Expr.Kind<>pekIdent then
|
||||||
|
ParseExcSyntaxError;
|
||||||
|
|
||||||
|
// read specialized type
|
||||||
ISE:=TInlineSpecializeExpr(CreateElement(TInlineSpecializeExpr,'',AParent,SrcPos));
|
ISE:=TInlineSpecializeExpr(CreateElement(TInlineSpecializeExpr,'',AParent,SrcPos));
|
||||||
ReadSpecializeArguments(ISE);
|
SpecType:=TPasSpecializeType(CreateElement(TPasSpecializeType,'',ISE,SrcPos));
|
||||||
ISE.NameExpr:=Result;
|
ISE.DestType:=SpecType;
|
||||||
|
ReadSpecializeArguments(SpecType);
|
||||||
|
// can't resolve SpecType.DestType here
|
||||||
|
|
||||||
|
// A<B> or something.A<B>
|
||||||
|
if Expr.Parent is TBinaryExpr then
|
||||||
|
begin
|
||||||
|
if TBinaryExpr(Expr.Parent).right<>Expr then
|
||||||
|
ParseExcSyntaxError;
|
||||||
|
TBinaryExpr(Expr.Parent).right:=ISE;
|
||||||
|
ISE.Parent:=Expr.Parent;
|
||||||
|
end;
|
||||||
|
SpecType.Expr:=Expr;
|
||||||
|
Expr.Parent:=SpecType;
|
||||||
|
if Expr=Result then
|
||||||
Result:=ISE;
|
Result:=ISE;
|
||||||
ISE:=nil;
|
ISE:=nil;
|
||||||
CanSpecialize:=aCannot;
|
CanSpecialize:=aCannot;
|
||||||
@ -4079,19 +4107,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
{$warn 5043 on}
|
{$warn 5043 on}
|
||||||
|
|
||||||
procedure TPasParser.ReadSpecializeArguments(Spec: TPasElement);
|
procedure TPasParser.ReadSpecializeArguments(Spec: TPasSpecializeType);
|
||||||
// after parsing CurToken is on tkGreaterThan
|
// after parsing CurToken is on tkGreaterThan
|
||||||
|
|
||||||
procedure AddParam(El: TPasElement);
|
|
||||||
begin
|
|
||||||
if Spec is TPasSpecializeType then
|
|
||||||
TPasSpecializeType(Spec).AddParam(El)
|
|
||||||
else if Spec is TInlineSpecializeExpr then
|
|
||||||
TInlineSpecializeExpr(Spec).AddParam(El)
|
|
||||||
else
|
|
||||||
ParseExcTokenError('[20190619112611] '+Spec.ClassName);
|
|
||||||
end;
|
|
||||||
|
|
||||||
Var
|
Var
|
||||||
TypeEl: TPasType;
|
TypeEl: TPasType;
|
||||||
begin
|
begin
|
||||||
@ -4100,7 +4117,7 @@ begin
|
|||||||
repeat
|
repeat
|
||||||
//writeln('ARG TPasParser.ReadSpecializeArguments ',CurTokenText,' ',CurTokenString);
|
//writeln('ARG TPasParser.ReadSpecializeArguments ',CurTokenText,' ',CurTokenString);
|
||||||
TypeEl:=ParseType(Spec,CurTokenPos,'');
|
TypeEl:=ParseType(Spec,CurTokenPos,'');
|
||||||
AddParam(TypeEl);
|
Spec.AddParam(TypeEl);
|
||||||
NextToken;
|
NextToken;
|
||||||
if CurToken=tkComma then
|
if CurToken=tkComma then
|
||||||
continue
|
continue
|
||||||
|
@ -40,6 +40,7 @@ type
|
|||||||
procedure TestGen_Record_SpecializeSelfInsideFail;
|
procedure TestGen_Record_SpecializeSelfInsideFail;
|
||||||
procedure TestGen_RecordAnoArray;
|
procedure TestGen_RecordAnoArray;
|
||||||
// ToDo: unitname.specialize TBird<word>.specialize
|
// ToDo: unitname.specialize TBird<word>.specialize
|
||||||
|
procedure TestGen_RecordNestedSpecialize;
|
||||||
|
|
||||||
// generic class
|
// generic class
|
||||||
procedure TestGen_Class;
|
procedure TestGen_Class;
|
||||||
@ -57,10 +58,11 @@ type
|
|||||||
// ToDo: ancestor cycle: TBird<T> = class(TBird<word>) fail
|
// ToDo: ancestor cycle: TBird<T> = class(TBird<word>) fail
|
||||||
// ToDo: class-of
|
// ToDo: class-of
|
||||||
// ToDo: UnitA.impl uses UnitB.intf uses UnitA.intf, UnitB has specialize of UnitA
|
// ToDo: UnitA.impl uses UnitB.intf uses UnitA.intf, UnitB has specialize of UnitA
|
||||||
procedure TestGen_NestedType;
|
procedure TestGen_Class_NestedType;
|
||||||
// ToDo: procedure TestGen_NestedDottedType;
|
// ToDo: procedure TestGen_NestedDottedType;
|
||||||
procedure TestGen_Class_Enums_NotPropagating;
|
procedure TestGen_Class_Enums_NotPropagating;
|
||||||
procedure TestGen_Class_List;
|
procedure TestGen_Class_List;
|
||||||
|
// ToDo: procedure TestGen_Class_SubClassType;
|
||||||
|
|
||||||
// generic external class
|
// generic external class
|
||||||
procedure TestGen_ExtClass_Array;
|
procedure TestGen_ExtClass_Array;
|
||||||
@ -84,6 +86,7 @@ type
|
|||||||
// generic statements
|
// generic statements
|
||||||
procedure TestGen_LocalVar;
|
procedure TestGen_LocalVar;
|
||||||
procedure TestGen_Statements;
|
procedure TestGen_Statements;
|
||||||
|
procedure TestGen_InlineSpecializeExpr;
|
||||||
// ToDo: for-in
|
// ToDo: for-in
|
||||||
procedure TestGen_TryExcept;
|
procedure TestGen_TryExcept;
|
||||||
// ToDo: call
|
// ToDo: call
|
||||||
@ -359,6 +362,21 @@ begin
|
|||||||
ParseProgram;
|
ParseProgram;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolveGenerics.TestGen_RecordNestedSpecialize;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'{$mode objfpc}',
|
||||||
|
'type',
|
||||||
|
' generic TBird<T> = record v: T; end;',
|
||||||
|
'var',
|
||||||
|
' a: specialize TBird<specialize TBird<word>>;',
|
||||||
|
'begin',
|
||||||
|
' a.v.v:=3;',
|
||||||
|
'']);
|
||||||
|
ParseProgram;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestResolveGenerics.TestGen_Class;
|
procedure TTestResolveGenerics.TestGen_Class;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
@ -589,7 +607,7 @@ begin
|
|||||||
CheckResolverException('type "TBird" is not yet completely defined',nTypeXIsNotYetCompletelyDefined);
|
CheckResolverException('type "TBird" is not yet completely defined',nTypeXIsNotYetCompletelyDefined);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestResolveGenerics.TestGen_NestedType;
|
procedure TTestResolveGenerics.TestGen_Class_NestedType;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
Add([
|
Add([
|
||||||
@ -849,6 +867,44 @@ begin
|
|||||||
ParseProgram;
|
ParseProgram;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolveGenerics.TestGen_InlineSpecializeExpr;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'{$mode objfpc}',
|
||||||
|
'type',
|
||||||
|
' TObject = class end;',
|
||||||
|
' generic TBird<T> = class',
|
||||||
|
' constructor Create;',
|
||||||
|
' end;',
|
||||||
|
' generic TAnt<U> = class',
|
||||||
|
' constructor Create;',
|
||||||
|
' end;',
|
||||||
|
'constructor TBird.Create;',
|
||||||
|
'var',
|
||||||
|
' a: TAnt<T>;',
|
||||||
|
' b: TAnt<word>;',
|
||||||
|
'begin',
|
||||||
|
' a:=TAnt<T>.create;',
|
||||||
|
' b:=TAnt<word>.create;',
|
||||||
|
'end;',
|
||||||
|
'constructor TAnt.Create;',
|
||||||
|
'var',
|
||||||
|
' i: TBird<U>;',
|
||||||
|
' j: TBird<word>;',
|
||||||
|
' k: TAnt<U>;',
|
||||||
|
'begin',
|
||||||
|
' i:=TBird<U>.create;',
|
||||||
|
' j:=TBird<word>.create;',
|
||||||
|
' k:=TAnt<U>.create;',
|
||||||
|
'end;',
|
||||||
|
'var a: TAnt<word>;',
|
||||||
|
'begin',
|
||||||
|
' a:=TAnt<word>.create;',
|
||||||
|
'']);
|
||||||
|
ParseProgram;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestResolveGenerics.TestGen_TryExcept;
|
procedure TTestResolveGenerics.TestGen_TryExcept;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
|
@ -844,6 +844,7 @@ type
|
|||||||
procedure Set_Variable_VarType(RefEl: TPasElement; Data: TObject);
|
procedure Set_Variable_VarType(RefEl: TPasElement; Data: TObject);
|
||||||
procedure Set_AliasType_DestType(RefEl: TPasElement; Data: TObject);
|
procedure Set_AliasType_DestType(RefEl: TPasElement; Data: TObject);
|
||||||
procedure Set_PointerType_DestType(RefEl: TPasElement; Data: TObject);
|
procedure Set_PointerType_DestType(RefEl: TPasElement; Data: TObject);
|
||||||
|
procedure Set_InlineSpecializeExpr_DestType(RefEl: TPasElement; Data: TObject);
|
||||||
procedure Set_ArrayType_ElType(RefEl: TPasElement; Data: TObject);
|
procedure Set_ArrayType_ElType(RefEl: TPasElement; Data: TObject);
|
||||||
procedure Set_FileType_ElType(RefEl: TPasElement; Data: TObject);
|
procedure Set_FileType_ElType(RefEl: TPasElement; Data: TObject);
|
||||||
procedure Set_SetType_EnumType(RefEl: TPasElement; Data: TObject);
|
procedure Set_SetType_EnumType(RefEl: TPasElement; Data: TObject);
|
||||||
@ -3327,8 +3328,7 @@ procedure TPCUWriter.WriteInlineSpecializeExpr(Obj: TJSONObject;
|
|||||||
Expr: TInlineSpecializeExpr; aContext: TPCUWriterContext);
|
Expr: TInlineSpecializeExpr; aContext: TPCUWriterContext);
|
||||||
begin
|
begin
|
||||||
WritePasExpr(Obj,Expr,pekSpecialize,eopNone,aContext);
|
WritePasExpr(Obj,Expr,pekSpecialize,eopNone,aContext);
|
||||||
WriteExpr(Obj,Expr,'Name',Expr.NameExpr,aContext);
|
WriteElType(Obj,Expr,'Dest',Expr.DestType,aContext);
|
||||||
WriteElementList(Obj,Expr,'Params',Expr.Params,aContext);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPCUWriter.WriteRangeType(Obj: TJSONObject; El: TPasRangeType;
|
procedure TPCUWriter.WriteRangeType(Obj: TJSONObject; El: TPasRangeType;
|
||||||
@ -4249,6 +4249,21 @@ begin
|
|||||||
RaiseMsg(20180211121757,El,GetObjName(RefEl));
|
RaiseMsg(20180211121757,El,GetObjName(RefEl));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPCUReader.Set_InlineSpecializeExpr_DestType(RefEl: TPasElement;
|
||||||
|
Data: TObject);
|
||||||
|
var
|
||||||
|
El: TInlineSpecializeExpr absolute Data;
|
||||||
|
begin
|
||||||
|
if RefEl is TPasSpecializeType then
|
||||||
|
begin
|
||||||
|
El.DestType:=TPasSpecializeType(RefEl);
|
||||||
|
if RefEl.Parent<>El then
|
||||||
|
RefEl.AddRef{$IFDEF CheckPasTreeRefCount}('TInlineSpecializeExpr.DestType'){$ENDIF};
|
||||||
|
end
|
||||||
|
else
|
||||||
|
RaiseMsg(20190815192420,El,GetObjName(RefEl));
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TPCUReader.Set_ArrayType_ElType(RefEl: TPasElement; Data: TObject);
|
procedure TPCUReader.Set_ArrayType_ElType(RefEl: TPasElement; Data: TObject);
|
||||||
var
|
var
|
||||||
El: TPasArrayType absolute Data;
|
El: TPasArrayType absolute Data;
|
||||||
@ -6708,10 +6723,7 @@ procedure TPCUReader.ReadInlineSpecializeExpr(Obj: TJSONObject;
|
|||||||
Expr: TInlineSpecializeExpr; aContext: TPCUReaderContext);
|
Expr: TInlineSpecializeExpr; aContext: TPCUReaderContext);
|
||||||
begin
|
begin
|
||||||
Expr.Kind:=pekSpecialize;
|
Expr.Kind:=pekSpecialize;
|
||||||
Expr.NameExpr:=ReadExpr(Obj,Expr,'Name',aContext);
|
ReadElType(Obj,'Dest',Expr,@Set_InlineSpecializeExpr_DestType,aContext);
|
||||||
ReadElementList(Obj,Expr,'Params',Expr.Params,
|
|
||||||
{$IFDEF CheckPasTreeRefCount}'TPasSpecializeType.Params'{$ELSE}true{$ENDIF},
|
|
||||||
aContext);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPCUReader.ReadRangeType(Obj: TJSONObject; El: TPasRangeType;
|
procedure TPCUReader.ReadRangeType(Obj: TJSONObject; El: TPasRangeType;
|
||||||
|
@ -1360,8 +1360,7 @@ end;
|
|||||||
procedure TCustomTestPrecompile.CheckRestoredInlineSpecializedExpr(
|
procedure TCustomTestPrecompile.CheckRestoredInlineSpecializedExpr(
|
||||||
const Path: string; Orig, Rest: TInlineSpecializeExpr);
|
const Path: string; Orig, Rest: TInlineSpecializeExpr);
|
||||||
begin
|
begin
|
||||||
CheckRestoredElement(Path+'.NameExpr',Orig.NameExpr,Rest.NameExpr);
|
CheckRestoredElement(Path+'.DestType',Orig.DestType,Rest.DestType);
|
||||||
CheckRestoredElementList(Path+'.Params',Orig.Params,Rest.Params);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomTestPrecompile.CheckRestoredRangeType(const Path: string;
|
procedure TCustomTestPrecompile.CheckRestoredRangeType(const Path: string;
|
||||||
|
Loading…
Reference in New Issue
Block a user