|
@@ -320,7 +320,7 @@ type
|
|
|
procedure ParseClassMembers(AType: TPasClassType);
|
|
|
procedure ProcessMethod(AType: TPasClassType; IsClass : Boolean; AVisibility : TPasMemberVisibility);
|
|
|
procedure ReadGenericArguments(List: TFPList; Parent: TPasElement);
|
|
|
- procedure ReadSpecializeArguments(Spec: TPasSpecializeType);
|
|
|
+ procedure ReadSpecializeArguments(Parent: TPasElement; Params: TFPList);
|
|
|
function ReadDottedIdentifier(Parent: TPasElement; out Expr: TPasExpr; NeedAsString: boolean): String;
|
|
|
function CheckProcedureArgs(Parent: TPasElement;
|
|
|
Args: TFPList; // list of TPasArgument
|
|
@@ -1695,8 +1695,6 @@ begin
|
|
|
else
|
|
|
begin
|
|
|
// simple type reference
|
|
|
- if not NeedExpr then
|
|
|
- ReleaseAndNil(TPasElement(Expr){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
|
|
|
Result:=ResolveTypeReference(Name,Parent);
|
|
|
end;
|
|
|
ok:=true;
|
|
@@ -1730,7 +1728,7 @@ begin
|
|
|
GenNameExpr:=nil; // ownership transferred to ST
|
|
|
end;
|
|
|
// read nested specialize arguments
|
|
|
- ReadSpecializeArguments(ST);
|
|
|
+ ReadSpecializeArguments(ST,ST.Params);
|
|
|
// Important: resolve type reference AFTER args, because arg count is needed
|
|
|
ST.DestType:=ResolveTypeReference(GenName,ST,ST.Params.Count);
|
|
|
|
|
@@ -2329,8 +2327,6 @@ var
|
|
|
SrcPos, ScrPos: TPasSourcePos;
|
|
|
ProcType: TProcType;
|
|
|
ProcExpr: TProcedureExpr;
|
|
|
- SpecType: TPasSpecializeType;
|
|
|
-
|
|
|
begin
|
|
|
Result:=nil;
|
|
|
CanSpecialize:=aCannot;
|
|
@@ -2502,7 +2498,7 @@ begin
|
|
|
// 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
|
|
|
+ if Expr.Kind=pekBinary then
|
|
|
begin
|
|
|
if Expr.OpCode<>eopSubIdent then
|
|
|
ParseExcSyntaxError;
|
|
@@ -2511,25 +2507,14 @@ begin
|
|
|
if Expr.Kind<>pekIdent then
|
|
|
ParseExcSyntaxError;
|
|
|
|
|
|
- // read specialized type
|
|
|
+ // read specialized params
|
|
|
ISE:=TInlineSpecializeExpr(CreateElement(TInlineSpecializeExpr,'',AParent,SrcPos));
|
|
|
- SpecType:=TPasSpecializeType(CreateElement(TPasSpecializeType,'',ISE,SrcPos));
|
|
|
- ISE.DestType:=SpecType;
|
|
|
- ReadSpecializeArguments(SpecType);
|
|
|
- // can't resolve SpecType.DestType here
|
|
|
+ ReadSpecializeArguments(ISE,ISE.Params);
|
|
|
|
|
|
// 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;
|
|
|
+ ISE.NameExpr:=Result;
|
|
|
+ Result.Parent:=ISE;
|
|
|
+ Result:=ISE;
|
|
|
ISE:=nil;
|
|
|
CanSpecialize:=aCannot;
|
|
|
NextToken;
|
|
@@ -4113,8 +4098,6 @@ Var
|
|
|
T : TPasGenericTemplateType;
|
|
|
Expr: TPasExpr;
|
|
|
TypeEl: TPasType;
|
|
|
- SrcPos: TPasSourcePos;
|
|
|
- ISE: TInlineSpecializeExpr;
|
|
|
begin
|
|
|
ExpectToken(tkLessThan);
|
|
|
repeat
|
|
@@ -4125,39 +4108,28 @@ begin
|
|
|
if Curtoken = tkColon then
|
|
|
repeat
|
|
|
NextToken;
|
|
|
- // comma separated list: identifier, class, record, constructor
|
|
|
+ // comma separated list of constraints: identifier, class, record, constructor
|
|
|
case CurToken of
|
|
|
tkclass,tkrecord,tkconstructor:
|
|
|
begin
|
|
|
if T.TypeConstraint='' then
|
|
|
T.TypeConstraint:=CurTokenString;
|
|
|
Expr:=CreatePrimitiveExpr(T,pekIdent,CurTokenText);
|
|
|
+ T.AddConstraint(Expr);
|
|
|
NextToken;
|
|
|
end;
|
|
|
tkIdentifier,tkspecialize:
|
|
|
begin
|
|
|
- SrcPos:=CurSourcePos;
|
|
|
- TypeEl:=ParseTypeReference(T,true,Expr);
|
|
|
- if TypeEl<>nil then
|
|
|
- begin
|
|
|
+ TypeEl:=ParseTypeReference(T,false,Expr);
|
|
|
+ if T.TypeConstraint='' then
|
|
|
T.TypeConstraint:=TypeEl.Name;
|
|
|
- if TypeEl is TPasSpecializeType then
|
|
|
- begin
|
|
|
- ISE:=TInlineSpecializeExpr(CreateElement(TInlineSpecializeExpr,'',T,SrcPos));
|
|
|
- ISE.DestType:=TPasSpecializeType(TypeEl);
|
|
|
- TypeEl.Parent:=ISE;
|
|
|
- Expr:=ISE;
|
|
|
- end
|
|
|
- else if TypeEl.Parent=T then
|
|
|
- ParseExc(nParserExpectTokenError,SParserExpectTokenError,['20190831211205:'+TypeEl.ClassName])
|
|
|
- else
|
|
|
- TypeEl.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
|
- end;
|
|
|
+ if (Expr<>nil) and (Expr.Parent=T) then
|
|
|
+ Expr.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
|
+ T.AddConstraint(TypeEl);
|
|
|
end;
|
|
|
else
|
|
|
CheckToken(tkIdentifier);
|
|
|
end;
|
|
|
- T.AddConstraint(Expr);
|
|
|
until CurToken<>tkComma;
|
|
|
Engine.FinishScope(stTypeDef,T);
|
|
|
until not (CurToken in [tkSemicolon,tkComma]);
|
|
@@ -4167,7 +4139,8 @@ begin
|
|
|
end;
|
|
|
{$warn 5043 on}
|
|
|
|
|
|
-procedure TPasParser.ReadSpecializeArguments(Spec: TPasSpecializeType);
|
|
|
+procedure TPasParser.ReadSpecializeArguments(Parent: TPasElement;
|
|
|
+ Params: TFPList);
|
|
|
// after parsing CurToken is on tkGreaterThan
|
|
|
Var
|
|
|
TypeEl: TPasType;
|
|
@@ -4176,8 +4149,8 @@ begin
|
|
|
CheckToken(tkLessThan);
|
|
|
repeat
|
|
|
//writeln('ARG TPasParser.ReadSpecializeArguments ',CurTokenText,' ',CurTokenString);
|
|
|
- TypeEl:=ParseType(Spec,CurTokenPos,'');
|
|
|
- Spec.AddParam(TypeEl);
|
|
|
+ TypeEl:=ParseType(Parent,CurTokenPos,'');
|
|
|
+ Params.Add(TypeEl);
|
|
|
NextToken;
|
|
|
if CurToken=tkComma then
|
|
|
continue
|