|
@@ -318,9 +318,9 @@ type
|
|
function GetProcedureClass(ProcType : TProcType): TPTreeElement;
|
|
function GetProcedureClass(ProcType : TProcType): TPTreeElement;
|
|
procedure ParseClassFields(AType: TPasClassType; const AVisibility: TPasMemberVisibility; IsClassField : Boolean);
|
|
procedure ParseClassFields(AType: TPasClassType; const AVisibility: TPasMemberVisibility; IsClassField : Boolean);
|
|
procedure ParseClassMembers(AType: TPasClassType);
|
|
procedure ParseClassMembers(AType: TPasClassType);
|
|
- procedure ProcessMethod(AType: TPasClassType; IsClass : Boolean; AVisibility : TPasMemberVisibility);
|
|
|
|
- procedure ReadGenericArguments(List : TFPList;Parent : TPasElement);
|
|
|
|
- procedure ReadSpecializeArguments(Spec: TPasSpecializeType);
|
|
|
|
|
|
+ procedure ProcessMethod(AType: TPasClassType; IsClass : Boolean; AVisibility : TPasMemberVisibility; MustBeGeneric: boolean);
|
|
|
|
+ procedure ReadGenericArguments(List: TFPList; Parent: TPasElement);
|
|
|
|
+ procedure ReadSpecializeArguments(Parent: TPasElement; Params: TFPList);
|
|
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
|
|
@@ -331,7 +331,8 @@ type
|
|
procedure ParseExcExpectedIdentifier;
|
|
procedure ParseExcExpectedIdentifier;
|
|
procedure ParseExcSyntaxError;
|
|
procedure ParseExcSyntaxError;
|
|
procedure ParseExcTokenError(const Arg: string);
|
|
procedure ParseExcTokenError(const Arg: string);
|
|
- procedure ParseTypeParamsNotAllowed;
|
|
|
|
|
|
+ procedure ParseExcTypeParamsNotAllowed;
|
|
|
|
+ procedure ParseExcExpectedAorB(const A, B: string);
|
|
function OpLevel(t: TToken): Integer;
|
|
function OpLevel(t: TToken): Integer;
|
|
Function TokenToExprOp (AToken : TToken) : TExprOpCode;
|
|
Function TokenToExprOp (AToken : TToken) : TExprOpCode;
|
|
function CreateElement(AClass: TPTreeElement; const AName: String; AParent: TPasElement): TPasElement;overload;
|
|
function CreateElement(AClass: TPTreeElement; const AName: String; AParent: TPasElement): TPasElement;overload;
|
|
@@ -433,7 +434,7 @@ type
|
|
// Constant declarations
|
|
// Constant declarations
|
|
function ParseConstDecl(Parent: TPasElement): TPasConst;
|
|
function ParseConstDecl(Parent: TPasElement): TPasConst;
|
|
function ParseResourcestringDecl(Parent: TPasElement): TPasResString;
|
|
function ParseResourcestringDecl(Parent: TPasElement): TPasResString;
|
|
- function ParseAttributes(Parent: TPasElement): TPasAttributes;
|
|
|
|
|
|
+ function ParseAttributes(Parent: TPasElement; Add: boolean): TPasAttributes;
|
|
// Variable handling. This includes parts of records
|
|
// Variable handling. This includes parts of records
|
|
procedure ParseVarDecl(Parent: TPasElement; List: TFPList);
|
|
procedure ParseVarDecl(Parent: TPasElement; List: TFPList);
|
|
procedure ParseInlineVarDecl(Parent: TPasElement; List: TFPList; AVisibility : TPasMemberVisibility = visDefault; ClosingBrace: Boolean = False);
|
|
procedure ParseInlineVarDecl(Parent: TPasElement; List: TFPList; AVisibility : TPasMemberVisibility = visDefault; ClosingBrace: Boolean = False);
|
|
@@ -458,7 +459,8 @@ type
|
|
procedure ParseProcAsmBlock(Parent: TProcedureBody);
|
|
procedure ParseProcAsmBlock(Parent: TProcedureBody);
|
|
// Function/Procedure declaration
|
|
// Function/Procedure declaration
|
|
function ParseProcedureOrFunctionDecl(Parent: TPasElement;
|
|
function ParseProcedureOrFunctionDecl(Parent: TPasElement;
|
|
- ProcType: TProcType; MustBeGeneric: boolean; AVisibility: TPasMemberVisibility = VisDefault): TPasProcedure;
|
|
|
|
|
|
+ ProcType: TProcType; MustBeGeneric: boolean;
|
|
|
|
+ AVisibility: TPasMemberVisibility = VisDefault): TPasProcedure;
|
|
procedure ParseArgList(Parent: TPasElement;
|
|
procedure ParseArgList(Parent: TPasElement;
|
|
Args: TFPList; // list of TPasArgument
|
|
Args: TFPList; // list of TPasArgument
|
|
EndToken: TToken);
|
|
EndToken: TToken);
|
|
@@ -1029,11 +1031,16 @@ begin
|
|
ParseExc(nParserExpectTokenError,SParserExpectTokenError,[Arg]);
|
|
ParseExc(nParserExpectTokenError,SParserExpectTokenError,[Arg]);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TPasParser.ParseTypeParamsNotAllowed;
|
|
|
|
|
|
+procedure TPasParser.ParseExcTypeParamsNotAllowed;
|
|
begin
|
|
begin
|
|
ParseExc(nParserTypeParamsNotAllowedOnType,sParserTypeParamsNotAllowedOnType,[]);
|
|
ParseExc(nParserTypeParamsNotAllowedOnType,sParserTypeParamsNotAllowedOnType,[]);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TPasParser.ParseExcExpectedAorB(const A, B: string);
|
|
|
|
+begin
|
|
|
|
+ ParseExc(nParserExpectToken2Error,SParserExpectToken2Error,[A,B]);
|
|
|
|
+end;
|
|
|
|
+
|
|
constructor TPasParser.Create(AScanner: TPascalScanner;
|
|
constructor TPasParser.Create(AScanner: TPascalScanner;
|
|
AFileResolver: TBaseFileResolver; AEngine: TPasTreeContainer);
|
|
AFileResolver: TBaseFileResolver; AEngine: TPasTreeContainer);
|
|
begin
|
|
begin
|
|
@@ -1570,7 +1577,8 @@ begin
|
|
ParseExcSyntaxError;
|
|
ParseExcSyntaxError;
|
|
UnGetToken;
|
|
UnGetToken;
|
|
end
|
|
end
|
|
- else if (CurToken = tkLessThan) then // A = B<t>;
|
|
|
|
|
|
+ else if (CurToken = tkLessThan)
|
|
|
|
+ and (MustBeSpecialize or (msDelphi in CurrentModeswitches)) then // A = B<t>;
|
|
begin
|
|
begin
|
|
Result:=ParseSpecializeType(Parent,TypeName,Name,Expr);
|
|
Result:=ParseSpecializeType(Parent,TypeName,Name,Expr);
|
|
ok:=true;
|
|
ok:=true;
|
|
@@ -1683,22 +1691,29 @@ begin
|
|
if CurToken=tkLessThan then
|
|
if CurToken=tkLessThan then
|
|
begin
|
|
begin
|
|
// specialize
|
|
// specialize
|
|
- Result:=ParseSpecializeType(Parent,'',Name,Expr);
|
|
|
|
- NextToken;
|
|
|
|
|
|
+ if IsSpecialize or (msDelphi in CurrentModeswitches) then
|
|
|
|
+ begin
|
|
|
|
+ Result:=ParseSpecializeType(Parent,'',Name,Expr);
|
|
|
|
+ NextToken;
|
|
|
|
+ end;
|
|
end
|
|
end
|
|
else if IsSpecialize then
|
|
else if IsSpecialize then
|
|
CheckToken(tkLessThan)
|
|
CheckToken(tkLessThan)
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
// simple type reference
|
|
// simple type reference
|
|
- if not NeedExpr then
|
|
|
|
- ReleaseAndNil(TPasElement(Expr){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
|
|
|
|
Result:=ResolveTypeReference(Name,Parent);
|
|
Result:=ResolveTypeReference(Name,Parent);
|
|
end;
|
|
end;
|
|
ok:=true;
|
|
ok:=true;
|
|
finally
|
|
finally
|
|
- if (not ok) and (Result<>nil) then
|
|
|
|
- Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
|
|
|
|
+ if not ok then
|
|
|
|
+ begin
|
|
|
|
+ if Result<>nil then
|
|
|
|
+ Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
|
|
+ ReleaseAndNil(TPasElement(Expr){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
|
|
|
|
+ end
|
|
|
|
+ else if (not NeedExpr) and (Expr<>nil) then
|
|
|
|
+ ReleaseAndNil(TPasElement(Expr){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1720,7 +1735,7 @@ begin
|
|
GenNameExpr:=nil; // ownership transferred to ST
|
|
GenNameExpr:=nil; // ownership transferred to ST
|
|
end;
|
|
end;
|
|
// read nested specialize arguments
|
|
// read nested specialize arguments
|
|
- ReadSpecializeArguments(ST);
|
|
|
|
|
|
+ ReadSpecializeArguments(ST,ST.Params);
|
|
// Important: resolve type reference AFTER args, because arg count is needed
|
|
// Important: resolve type reference AFTER args, because arg count is needed
|
|
ST.DestType:=ResolveTypeReference(GenName,ST,ST.Params.Count);
|
|
ST.DestType:=ResolveTypeReference(GenName,ST,ST.Params.Count);
|
|
|
|
|
|
@@ -1741,11 +1756,27 @@ function TPasParser.ParsePointerType(Parent: TPasElement;
|
|
|
|
|
|
var
|
|
var
|
|
ok: Boolean;
|
|
ok: Boolean;
|
|
|
|
+ Name: String;
|
|
begin
|
|
begin
|
|
Result := TPasPointerType(CreateElement(TPasPointerType, TypeName, Parent, NamePos));
|
|
Result := TPasPointerType(CreateElement(TPasPointerType, TypeName, Parent, NamePos));
|
|
ok:=false;
|
|
ok:=false;
|
|
Try
|
|
Try
|
|
- TPasPointerType(Result).DestType := ParseType(Result,CurSourcePos);
|
|
|
|
|
|
+ // only allowed: ^dottedidentifer
|
|
|
|
+ // forbidden: ^^identifier, ^array of word, ^A<B>
|
|
|
|
+ ExpectIdentifier;
|
|
|
|
+ Name:=CurTokenString;
|
|
|
|
+ repeat
|
|
|
|
+ NextToken;
|
|
|
|
+ if CurToken=tkDot then
|
|
|
|
+ begin
|
|
|
|
+ ExpectIdentifier;
|
|
|
|
+ Name := Name+'.'+CurTokenString;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ break;
|
|
|
|
+ until false;
|
|
|
|
+ UngetToken;
|
|
|
|
+ Result.DestType:=ResolveTypeReference(Name,Result);
|
|
Engine.FinishScope(stTypeDef,Result);
|
|
Engine.FinishScope(stTypeDef,Result);
|
|
ok:=true;
|
|
ok:=true;
|
|
finally
|
|
finally
|
|
@@ -2303,8 +2334,6 @@ var
|
|
SrcPos, ScrPos: TPasSourcePos;
|
|
SrcPos, ScrPos: TPasSourcePos;
|
|
ProcType: TProcType;
|
|
ProcType: TProcType;
|
|
ProcExpr: TProcedureExpr;
|
|
ProcExpr: TProcedureExpr;
|
|
- SpecType: TPasSpecializeType;
|
|
|
|
-
|
|
|
|
begin
|
|
begin
|
|
Result:=nil;
|
|
Result:=nil;
|
|
CanSpecialize:=aCannot;
|
|
CanSpecialize:=aCannot;
|
|
@@ -2315,7 +2344,10 @@ begin
|
|
tkNumber: Last:=CreatePrimitiveExpr(AParent,pekNumber,CurTokenString);
|
|
tkNumber: Last:=CreatePrimitiveExpr(AParent,pekNumber,CurTokenString);
|
|
tkIdentifier:
|
|
tkIdentifier:
|
|
begin
|
|
begin
|
|
- CanSpecialize:=aCan;
|
|
|
|
|
|
+ if msDelphi in CurrentModeswitches then
|
|
|
|
+ CanSpecialize:=aCan
|
|
|
|
+ else
|
|
|
|
+ CanSpecialize:=aCannot;
|
|
aName:=CurTokenText;
|
|
aName:=CurTokenText;
|
|
if (CompareText(aName,'self')=0) and not (tkself in Scanner.NonTokens) then
|
|
if (CompareText(aName,'self')=0) and not (tkself in Scanner.NonTokens) then
|
|
Last:=CreateSelfExpr(AParent)
|
|
Last:=CreateSelfExpr(AParent)
|
|
@@ -2473,7 +2505,7 @@ begin
|
|
// an inline specialization (e.g. A<B,C> or something.A<B>)
|
|
// an inline specialization (e.g. A<B,C> or something.A<B>)
|
|
// check expression in front is an identifier
|
|
// check expression in front is an identifier
|
|
Expr:=Result;
|
|
Expr:=Result;
|
|
- while Expr.Kind=pekBinary do
|
|
|
|
|
|
+ if Expr.Kind=pekBinary then
|
|
begin
|
|
begin
|
|
if Expr.OpCode<>eopSubIdent then
|
|
if Expr.OpCode<>eopSubIdent then
|
|
ParseExcSyntaxError;
|
|
ParseExcSyntaxError;
|
|
@@ -2482,25 +2514,14 @@ begin
|
|
if Expr.Kind<>pekIdent then
|
|
if Expr.Kind<>pekIdent then
|
|
ParseExcSyntaxError;
|
|
ParseExcSyntaxError;
|
|
|
|
|
|
- // read specialized type
|
|
|
|
|
|
+ // read specialized params
|
|
ISE:=TInlineSpecializeExpr(CreateElement(TInlineSpecializeExpr,'',AParent,SrcPos));
|
|
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>
|
|
// 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;
|
|
ISE:=nil;
|
|
CanSpecialize:=aCannot;
|
|
CanSpecialize:=aCannot;
|
|
NextToken;
|
|
NextToken;
|
|
@@ -3427,9 +3448,8 @@ var
|
|
ExpEl: TPasExportSymbol;
|
|
ExpEl: TPasExportSymbol;
|
|
PropEl : TPasProperty;
|
|
PropEl : TPasProperty;
|
|
PT : TProcType;
|
|
PT : TProcType;
|
|
- ok: Boolean;
|
|
|
|
|
|
+ ok, MustBeGeneric: Boolean;
|
|
Proc: TPasProcedure;
|
|
Proc: TPasProcedure;
|
|
- Attr: TPasAttributes;
|
|
|
|
CurEl: TPasElement;
|
|
CurEl: TPasElement;
|
|
begin
|
|
begin
|
|
CurBlock := declNone;
|
|
CurBlock := declNone;
|
|
@@ -3462,7 +3482,9 @@ begin
|
|
ParseImplementation;
|
|
ParseImplementation;
|
|
end;
|
|
end;
|
|
break;
|
|
break;
|
|
- end;
|
|
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ ParseExcSyntaxError;
|
|
tkinitialization:
|
|
tkinitialization:
|
|
if (Declarations is TInterfaceSection)
|
|
if (Declarations is TInterfaceSection)
|
|
or ((Declarations is TImplementationSection) and not (Declarations is TProgramSection)) then
|
|
or ((Declarations is TImplementationSection) and not (Declarations is TProgramSection)) then
|
|
@@ -3470,7 +3492,9 @@ begin
|
|
SetBlock(declNone);
|
|
SetBlock(declNone);
|
|
ParseInitialization;
|
|
ParseInitialization;
|
|
break;
|
|
break;
|
|
- end;
|
|
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ ParseExcSyntaxError;
|
|
tkfinalization:
|
|
tkfinalization:
|
|
if (Declarations is TInterfaceSection)
|
|
if (Declarations is TInterfaceSection)
|
|
or ((Declarations is TImplementationSection) and not (Declarations is TProgramSection)) then
|
|
or ((Declarations is TImplementationSection) and not (Declarations is TProgramSection)) then
|
|
@@ -3510,139 +3534,143 @@ begin
|
|
SetBlock(declProperty);
|
|
SetBlock(declProperty);
|
|
tkProcedure, tkFunction, tkConstructor, tkDestructor, tkOperator:
|
|
tkProcedure, tkFunction, tkConstructor, tkDestructor, tkOperator:
|
|
begin
|
|
begin
|
|
|
|
+ MustBeGeneric:=(not (msDelphi in CurrentModeswitches)) and (GetPrevToken=tkgeneric);
|
|
SetBlock(declNone);
|
|
SetBlock(declNone);
|
|
SaveComments;
|
|
SaveComments;
|
|
pt:=GetProcTypeFromToken(CurToken);
|
|
pt:=GetProcTypeFromToken(CurToken);
|
|
- AddProcOrFunction(Declarations, ParseProcedureOrFunctionDecl(Declarations, pt, false));
|
|
|
|
|
|
+ AddProcOrFunction(Declarations, ParseProcedureOrFunctionDecl(Declarations, pt, MustBeGeneric));
|
|
end;
|
|
end;
|
|
tkClass:
|
|
tkClass:
|
|
begin
|
|
begin
|
|
- SetBlock(declNone);
|
|
|
|
- SaveComments;
|
|
|
|
- NextToken;
|
|
|
|
- If CurToken in [tkprocedure,tkFunction,tkConstructor,tkDestructor] then
|
|
|
|
- begin
|
|
|
|
- pt:=GetProcTypeFromToken(CurToken,True);
|
|
|
|
- AddProcOrFunction(Declarations,ParseProcedureOrFunctionDecl(Declarations, pt, false));
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- CheckToken(tkprocedure);
|
|
|
|
|
|
+ MustBeGeneric:=(not (msDelphi in CurrentModeswitches)) and (GetPrevToken=tkgeneric);
|
|
|
|
+ SetBlock(declNone);
|
|
|
|
+ SaveComments;
|
|
|
|
+ NextToken;
|
|
|
|
+ If CurToken in [tkprocedure,tkFunction,tkConstructor,tkDestructor] then
|
|
|
|
+ begin
|
|
|
|
+ pt:=GetProcTypeFromToken(CurToken,True);
|
|
|
|
+ AddProcOrFunction(Declarations,ParseProcedureOrFunctionDecl(Declarations, pt, MustBeGeneric));
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ CheckToken(tkprocedure);
|
|
end;
|
|
end;
|
|
tkIdentifier:
|
|
tkIdentifier:
|
|
begin
|
|
begin
|
|
- Scanner.UnSetTokenOption(toOperatorToken);
|
|
|
|
- SaveComments;
|
|
|
|
- case CurBlock of
|
|
|
|
- declConst:
|
|
|
|
- begin
|
|
|
|
- ConstEl := ParseConstDecl(Declarations);
|
|
|
|
- Declarations.Declarations.Add(ConstEl);
|
|
|
|
- Declarations.Consts.Add(ConstEl);
|
|
|
|
- Engine.FinishScope(stDeclaration,ConstEl);
|
|
|
|
- end;
|
|
|
|
- declResourcestring:
|
|
|
|
|
|
+ Scanner.UnSetTokenOption(toOperatorToken);
|
|
|
|
+ SaveComments;
|
|
|
|
+ case CurBlock of
|
|
|
|
+ declConst:
|
|
|
|
+ begin
|
|
|
|
+ ConstEl := ParseConstDecl(Declarations);
|
|
|
|
+ Declarations.Declarations.Add(ConstEl);
|
|
|
|
+ Declarations.Consts.Add(ConstEl);
|
|
|
|
+ Engine.FinishScope(stDeclaration,ConstEl);
|
|
|
|
+ end;
|
|
|
|
+ declResourcestring:
|
|
|
|
+ begin
|
|
|
|
+ ResStrEl := ParseResourcestringDecl(Declarations);
|
|
|
|
+ Declarations.Declarations.Add(ResStrEl);
|
|
|
|
+ Declarations.ResStrings.Add(ResStrEl);
|
|
|
|
+ Engine.FinishScope(stResourceString,ResStrEl);
|
|
|
|
+ end;
|
|
|
|
+ declType:
|
|
|
|
+ begin
|
|
|
|
+ TypeEl := ParseTypeDecl(Declarations);
|
|
|
|
+ // Scanner.SetForceCaret(OldForceCaret); // It may have been switched off
|
|
|
|
+ if Assigned(TypeEl) then // !!!
|
|
begin
|
|
begin
|
|
- ResStrEl := ParseResourcestringDecl(Declarations);
|
|
|
|
- Declarations.Declarations.Add(ResStrEl);
|
|
|
|
- Declarations.ResStrings.Add(ResStrEl);
|
|
|
|
- Engine.FinishScope(stResourceString,ResStrEl);
|
|
|
|
- end;
|
|
|
|
- declType:
|
|
|
|
|
|
+ Declarations.Declarations.Add(TypeEl);
|
|
|
|
+ {$IFDEF CheckPasTreeRefCount}if TypeEl.RefIds.IndexOf('CreateElement')>=0 then TypeEl.ChangeRefId('CreateElement','TPasDeclarations.Children');{$ENDIF}
|
|
|
|
+ if (TypeEl.ClassType = TPasClassType)
|
|
|
|
+ and (not (po_keepclassforward in Options)) then
|
|
begin
|
|
begin
|
|
- TypeEl := ParseTypeDecl(Declarations);
|
|
|
|
- // Scanner.SetForceCaret(OldForceCaret); // It may have been switched off
|
|
|
|
- if Assigned(TypeEl) then // !!!
|
|
|
|
- begin
|
|
|
|
- Declarations.Declarations.Add(TypeEl);
|
|
|
|
- {$IFDEF CheckPasTreeRefCount}if TypeEl.RefIds.IndexOf('CreateElement')>=0 then TypeEl.ChangeRefId('CreateElement','TPasDeclarations.Children');{$ENDIF}
|
|
|
|
- if (TypeEl.ClassType = TPasClassType)
|
|
|
|
- and (not (po_keepclassforward in Options)) then
|
|
|
|
|
|
+ // Remove previous forward declarations, if necessary
|
|
|
|
+ for i := 0 to Declarations.Classes.Count - 1 do
|
|
begin
|
|
begin
|
|
- // Remove previous forward declarations, if necessary
|
|
|
|
- for i := 0 to Declarations.Classes.Count - 1 do
|
|
|
|
|
|
+ ClassEl := TPasClassType(Declarations.Classes[i]);
|
|
|
|
+ if CompareText(ClassEl.Name, TypeEl.Name) = 0 then
|
|
begin
|
|
begin
|
|
- ClassEl := TPasClassType(Declarations.Classes[i]);
|
|
|
|
- if CompareText(ClassEl.Name, TypeEl.Name) = 0 then
|
|
|
|
- begin
|
|
|
|
- Declarations.Classes.Delete(i);
|
|
|
|
- for j := 0 to Declarations.Declarations.Count - 1 do
|
|
|
|
- if CompareText(TypeEl.Name,
|
|
|
|
- TPasElement(Declarations.Declarations[j]).Name) = 0 then
|
|
|
|
- begin
|
|
|
|
- Declarations.Declarations.Delete(j);
|
|
|
|
- break;
|
|
|
|
- end;
|
|
|
|
- ClassEl.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
|
|
- break;
|
|
|
|
- end;
|
|
|
|
|
|
+ Declarations.Classes.Delete(i);
|
|
|
|
+ for j := 0 to Declarations.Declarations.Count - 1 do
|
|
|
|
+ if CompareText(TypeEl.Name,
|
|
|
|
+ TPasElement(Declarations.Declarations[j]).Name) = 0 then
|
|
|
|
+ begin
|
|
|
|
+ Declarations.Declarations.Delete(j);
|
|
|
|
+ break;
|
|
|
|
+ end;
|
|
|
|
+ ClassEl.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
|
|
+ break;
|
|
end;
|
|
end;
|
|
- // Add the new class to the class list
|
|
|
|
- Declarations.Classes.Add(TypeEl)
|
|
|
|
- end else
|
|
|
|
- Declarations.Types.Add(TypeEl);
|
|
|
|
end;
|
|
end;
|
|
|
|
+ // Add the new class to the class list
|
|
|
|
+ Declarations.Classes.Add(TypeEl)
|
|
|
|
+ end else
|
|
|
|
+ Declarations.Types.Add(TypeEl);
|
|
end;
|
|
end;
|
|
- declExports:
|
|
|
|
|
|
+ end;
|
|
|
|
+ declExports:
|
|
|
|
+ begin
|
|
|
|
+ List := TFPList.Create;
|
|
|
|
+ try
|
|
|
|
+ ok:=false;
|
|
|
|
+ try
|
|
|
|
+ ParseExportDecl(Declarations, List);
|
|
|
|
+ ok:=true;
|
|
|
|
+ finally
|
|
|
|
+ if not ok then
|
|
|
|
+ for i := 0 to List.Count - 1 do
|
|
|
|
+ TPasExportSymbol(List[i]).Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
|
|
+ end;
|
|
|
|
+ for i := 0 to List.Count - 1 do
|
|
begin
|
|
begin
|
|
|
|
+ ExpEl := TPasExportSymbol(List[i]);
|
|
|
|
+ Declarations.Declarations.Add(ExpEl);
|
|
|
|
+ {$IFDEF CheckPasTreeRefCount}ExpEl.ChangeRefId('CreateElement','TPasDeclarations.Children');{$ENDIF}
|
|
|
|
+ Declarations.ExportSymbols.Add(ExpEl);
|
|
|
|
+ end;
|
|
|
|
+ finally
|
|
|
|
+ List.Free;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ declVar, declThreadVar:
|
|
|
|
+ begin
|
|
List := TFPList.Create;
|
|
List := TFPList.Create;
|
|
try
|
|
try
|
|
- ok:=false;
|
|
|
|
- try
|
|
|
|
- ParseExportDecl(Declarations, List);
|
|
|
|
- ok:=true;
|
|
|
|
- finally
|
|
|
|
- if not ok then
|
|
|
|
- for i := 0 to List.Count - 1 do
|
|
|
|
- TPasExportSymbol(List[i]).Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
|
|
- end;
|
|
|
|
|
|
+ ParseVarDecl(Declarations, List);
|
|
for i := 0 to List.Count - 1 do
|
|
for i := 0 to List.Count - 1 do
|
|
begin
|
|
begin
|
|
- ExpEl := TPasExportSymbol(List[i]);
|
|
|
|
- Declarations.Declarations.Add(ExpEl);
|
|
|
|
- {$IFDEF CheckPasTreeRefCount}ExpEl.ChangeRefId('CreateElement','TPasDeclarations.Children');{$ENDIF}
|
|
|
|
- Declarations.ExportSymbols.Add(ExpEl);
|
|
|
|
|
|
+ CurEl := TPasElement(List[i]);
|
|
|
|
+ Declarations.Declarations.Add(CurEl);
|
|
|
|
+ if CurEl.ClassType=TPasAttributes then
|
|
|
|
+ Declarations.Attributes.Add(CurEl)
|
|
|
|
+ else
|
|
|
|
+ Declarations.Variables.Add(TPasVariable(CurEl));
|
|
|
|
+ Engine.FinishScope(stDeclaration,CurEl);
|
|
end;
|
|
end;
|
|
|
|
+ CheckToken(tkSemicolon);
|
|
finally
|
|
finally
|
|
List.Free;
|
|
List.Free;
|
|
end;
|
|
end;
|
|
- end;
|
|
|
|
- declVar, declThreadVar:
|
|
|
|
- begin
|
|
|
|
- List := TFPList.Create;
|
|
|
|
- try
|
|
|
|
- ParseVarDecl(Declarations, List);
|
|
|
|
- for i := 0 to List.Count - 1 do
|
|
|
|
- begin
|
|
|
|
- CurEl := TPasElement(List[i]);
|
|
|
|
- Declarations.Declarations.Add(CurEl);
|
|
|
|
- if CurEl.ClassType=TPasAttributes then
|
|
|
|
- Declarations.Attributes.Add(CurEl)
|
|
|
|
- else
|
|
|
|
- Declarations.Variables.Add(TPasVariable(CurEl));
|
|
|
|
- Engine.FinishScope(stDeclaration,CurEl);
|
|
|
|
- end;
|
|
|
|
- CheckToken(tkSemicolon);
|
|
|
|
- finally
|
|
|
|
- List.Free;
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- declProperty:
|
|
|
|
- begin
|
|
|
|
- PropEl:=ParseProperty(Declarations,CurtokenString,visDefault,false);
|
|
|
|
- Declarations.Declarations.Add(PropEl);
|
|
|
|
- {$IFDEF CheckPasTreeRefCount}PropEl.ChangeRefId('CreateElement','TPasDeclarations.Children');{$ENDIF}
|
|
|
|
- Declarations.Properties.Add(PropEl);
|
|
|
|
- Engine.FinishScope(stDeclaration,PropEl);
|
|
|
|
- end;
|
|
|
|
- else
|
|
|
|
- ParseExcSyntaxError;
|
|
|
|
- end;
|
|
|
|
|
|
+ end;
|
|
|
|
+ declProperty:
|
|
|
|
+ begin
|
|
|
|
+ PropEl:=ParseProperty(Declarations,CurtokenString,visDefault,false);
|
|
|
|
+ Declarations.Declarations.Add(PropEl);
|
|
|
|
+ {$IFDEF CheckPasTreeRefCount}PropEl.ChangeRefId('CreateElement','TPasDeclarations.Children');{$ENDIF}
|
|
|
|
+ Declarations.Properties.Add(PropEl);
|
|
|
|
+ Engine.FinishScope(stDeclaration,PropEl);
|
|
|
|
+ end;
|
|
|
|
+ else
|
|
|
|
+ ParseExcSyntaxError;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
tkGeneric:
|
|
tkGeneric:
|
|
begin
|
|
begin
|
|
NextToken;
|
|
NextToken;
|
|
if (CurToken in [tkprocedure,tkfunction]) then
|
|
if (CurToken in [tkprocedure,tkfunction]) then
|
|
begin
|
|
begin
|
|
|
|
+ if msDelphi in CurrentModeswitches then
|
|
|
|
+ ParseExcSyntaxError; // inconsistency, tkGeneric should be in Scanner.NonTokens
|
|
SetBlock(declNone);
|
|
SetBlock(declNone);
|
|
UngetToken;
|
|
UngetToken;
|
|
end;
|
|
end;
|
|
@@ -3730,12 +3758,7 @@ begin
|
|
end;
|
|
end;
|
|
tkSquaredBraceOpen:
|
|
tkSquaredBraceOpen:
|
|
if msPrefixedAttributes in CurrentModeSwitches then
|
|
if msPrefixedAttributes in CurrentModeSwitches then
|
|
- begin
|
|
|
|
- Attr:=ParseAttributes(Declarations);
|
|
|
|
- Declarations.Declarations.Add(Attr);
|
|
|
|
- Declarations.Attributes.Add(Attr);
|
|
|
|
- Engine.FinishScope(stDeclaration,Attr);
|
|
|
|
- end
|
|
|
|
|
|
+ ParseAttributes(Declarations,true)
|
|
else
|
|
else
|
|
ParseExcSyntaxError;
|
|
ParseExcSyntaxError;
|
|
else
|
|
else
|
|
@@ -4028,11 +4051,14 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TPasParser.ParseAttributes(Parent: TPasElement): TPasAttributes;
|
|
|
|
|
|
+function TPasParser.ParseAttributes(Parent: TPasElement; Add: boolean
|
|
|
|
+ ): TPasAttributes;
|
|
|
|
+// returns with CurToken at tkSquaredBraceClose
|
|
var
|
|
var
|
|
Expr, Arg: TPasExpr;
|
|
Expr, Arg: TPasExpr;
|
|
Attributes: TPasAttributes;
|
|
Attributes: TPasAttributes;
|
|
Params: TParamsExpr;
|
|
Params: TParamsExpr;
|
|
|
|
+ Decls: TPasDeclarations;
|
|
begin
|
|
begin
|
|
Result:=nil;
|
|
Result:=nil;
|
|
Attributes:=TPasAttributes(CreateElement(TPasAttributes,'',Parent));
|
|
Attributes:=TPasAttributes(CreateElement(TPasAttributes,'',Parent));
|
|
@@ -4068,6 +4094,20 @@ begin
|
|
until CurToken<>tkComma;
|
|
until CurToken<>tkComma;
|
|
CheckToken(tkSquaredBraceClose);
|
|
CheckToken(tkSquaredBraceClose);
|
|
Result:=Attributes;
|
|
Result:=Attributes;
|
|
|
|
+ if Add then
|
|
|
|
+ begin
|
|
|
|
+ if Parent is TPasDeclarations then
|
|
|
|
+ begin
|
|
|
|
+ Decls:=TPasDeclarations(Parent);
|
|
|
|
+ Decls.Declarations.Add(Result);
|
|
|
|
+ Decls.Attributes.Add(Result);
|
|
|
|
+ end
|
|
|
|
+ else if Parent is TPasMembersType then
|
|
|
|
+ TPasMembersType(Parent).Members.Add(Result)
|
|
|
|
+ else
|
|
|
|
+ ParseExcTokenError('[20190922193803]');
|
|
|
|
+ Engine.FinishScope(stDeclaration,Result);
|
|
|
|
+ end;
|
|
finally
|
|
finally
|
|
if Result=nil then
|
|
if Result=nil then
|
|
begin
|
|
begin
|
|
@@ -4094,36 +4134,38 @@ begin
|
|
if Curtoken = tkColon then
|
|
if Curtoken = tkColon then
|
|
repeat
|
|
repeat
|
|
NextToken;
|
|
NextToken;
|
|
- // comma separated list: identifier, class, record, constructor
|
|
|
|
- if CurToken in [tkclass,tkrecord,tkconstructor] then
|
|
|
|
|
|
+ // comma separated list of constraints: identifier, class, record, constructor
|
|
|
|
+ case CurToken of
|
|
|
|
+ tkclass,tkrecord,tkconstructor:
|
|
begin
|
|
begin
|
|
if T.TypeConstraint='' then
|
|
if T.TypeConstraint='' then
|
|
T.TypeConstraint:=CurTokenString;
|
|
T.TypeConstraint:=CurTokenString;
|
|
Expr:=CreatePrimitiveExpr(T,pekIdent,CurTokenText);
|
|
Expr:=CreatePrimitiveExpr(T,pekIdent,CurTokenText);
|
|
|
|
+ T.AddConstraint(Expr);
|
|
NextToken;
|
|
NextToken;
|
|
- end
|
|
|
|
- else if CurToken=tkIdentifier then
|
|
|
|
|
|
+ end;
|
|
|
|
+ tkIdentifier,tkspecialize:
|
|
begin
|
|
begin
|
|
- TypeEl:=ParseTypeReference(Parent,true,Expr);
|
|
|
|
- if TypeEl<>nil then
|
|
|
|
- begin
|
|
|
|
|
|
+ TypeEl:=ParseTypeReference(T,false,Expr);
|
|
|
|
+ if T.TypeConstraint='' then
|
|
T.TypeConstraint:=TypeEl.Name;
|
|
T.TypeConstraint:=TypeEl.Name;
|
|
- TypeEl.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
|
|
- end;
|
|
|
|
- end
|
|
|
|
|
|
+ if (Expr<>nil) and (Expr.Parent=T) then
|
|
|
|
+ Expr.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
|
|
+ T.AddConstraint(TypeEl);
|
|
|
|
+ end;
|
|
else
|
|
else
|
|
CheckToken(tkIdentifier);
|
|
CheckToken(tkIdentifier);
|
|
- T.AddConstraint(Expr);
|
|
|
|
|
|
+ end;
|
|
until CurToken<>tkComma;
|
|
until CurToken<>tkComma;
|
|
Engine.FinishScope(stTypeDef,T);
|
|
Engine.FinishScope(stTypeDef,T);
|
|
until not (CurToken in [tkSemicolon,tkComma]);
|
|
until not (CurToken in [tkSemicolon,tkComma]);
|
|
if CurToken<>tkGreaterThan then
|
|
if CurToken<>tkGreaterThan then
|
|
- ParseExc(nParserExpectToken2Error,SParserExpectToken2Error,
|
|
|
|
- [TokenInfos[tkComma], TokenInfos[tkGreaterThan]]);
|
|
|
|
|
|
+ ParseExcExpectedAorB(TokenInfos[tkComma], TokenInfos[tkGreaterThan]);
|
|
end;
|
|
end;
|
|
{$warn 5043 on}
|
|
{$warn 5043 on}
|
|
|
|
|
|
-procedure TPasParser.ReadSpecializeArguments(Spec: TPasSpecializeType);
|
|
|
|
|
|
+procedure TPasParser.ReadSpecializeArguments(Parent: TPasElement;
|
|
|
|
+ Params: TFPList);
|
|
// after parsing CurToken is on tkGreaterThan
|
|
// after parsing CurToken is on tkGreaterThan
|
|
Var
|
|
Var
|
|
TypeEl: TPasType;
|
|
TypeEl: TPasType;
|
|
@@ -4132,8 +4174,8 @@ begin
|
|
CheckToken(tkLessThan);
|
|
CheckToken(tkLessThan);
|
|
repeat
|
|
repeat
|
|
//writeln('ARG TPasParser.ReadSpecializeArguments ',CurTokenText,' ',CurTokenString);
|
|
//writeln('ARG TPasParser.ReadSpecializeArguments ',CurTokenText,' ',CurTokenString);
|
|
- TypeEl:=ParseType(Spec,CurTokenPos,'');
|
|
|
|
- Spec.AddParam(TypeEl);
|
|
|
|
|
|
+ TypeEl:=ParseType(Parent,CurTokenPos,'');
|
|
|
|
+ Params.Add(TypeEl);
|
|
NextToken;
|
|
NextToken;
|
|
if CurToken=tkComma then
|
|
if CurToken=tkComma then
|
|
continue
|
|
continue
|
|
@@ -4145,8 +4187,7 @@ begin
|
|
else if CurToken=tkGreaterThan then
|
|
else if CurToken=tkGreaterThan then
|
|
break
|
|
break
|
|
else
|
|
else
|
|
- ParseExc(nParserExpectToken2Error,SParserExpectToken2Error,
|
|
|
|
- [TokenInfos[tkComma], TokenInfos[tkGreaterThan]]);
|
|
|
|
|
|
+ ParseExcExpectedAorB(TokenInfos[tkComma], TokenInfos[tkGreaterThan]);
|
|
until false;
|
|
until false;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -4313,6 +4354,36 @@ function TPasParser.ParseGenericTypeDecl(Parent: TPasElement;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ procedure ParseProcType(const TypeName: string;
|
|
|
|
+ const NamePos: TPasSourcePos; TypeParams: TFPList;
|
|
|
|
+ IsReferenceTo: boolean);
|
|
|
|
+ var
|
|
|
|
+ ProcTypeEl: TPasProcedureType;
|
|
|
|
+ ProcType: TProcType;
|
|
|
|
+ begin
|
|
|
|
+ case CurToken of
|
|
|
|
+ tkFunction:
|
|
|
|
+ begin
|
|
|
|
+ ProcTypeEl := CreateFunctionType(TypeName, 'Result', Parent, False,
|
|
|
|
+ NamePos, TypeParams);
|
|
|
|
+ ProcType:=ptFunction;
|
|
|
|
+ end;
|
|
|
|
+ tkprocedure:
|
|
|
|
+ begin
|
|
|
|
+ ProcTypeEl := TPasProcedureType(CreateElement(TPasProcedureType,
|
|
|
|
+ TypeName, Parent, visDefault, NamePos, TypeParams));
|
|
|
|
+ ProcType:=ptProcedure;
|
|
|
|
+ end;
|
|
|
|
+ else
|
|
|
|
+ ParseExcTokenError('procedure or function');
|
|
|
|
+ end;
|
|
|
|
+ ProcTypeEl.IsReferenceTo:=IsReferenceTo;
|
|
|
|
+ if AddToParent and (Parent is TPasDeclarations) then
|
|
|
|
+ TPasDeclarations(Parent).Functions.Add(ProcTypeEl);
|
|
|
|
+ InitGenericType(ProcTypeEl,TypeParams);
|
|
|
|
+ ParseProcedureOrFunction(ProcTypeEl, ProcTypeEl, ProcType, True);
|
|
|
|
+ end;
|
|
|
|
+
|
|
var
|
|
var
|
|
TypeName, AExternalNameSpace, AExternalName: String;
|
|
TypeName, AExternalNameSpace, AExternalName: String;
|
|
NamePos: TPasSourcePos;
|
|
NamePos: TPasSourcePos;
|
|
@@ -4320,8 +4391,6 @@ var
|
|
ClassEl: TPasClassType;
|
|
ClassEl: TPasClassType;
|
|
RecordEl: TPasRecordType;
|
|
RecordEl: TPasRecordType;
|
|
ArrEl: TPasArrayType;
|
|
ArrEl: TPasArrayType;
|
|
- ProcTypeEl: TPasProcedureType;
|
|
|
|
- ProcType: TProcType;
|
|
|
|
i: Integer;
|
|
i: Integer;
|
|
AObjKind: TPasObjKind;
|
|
AObjKind: TPasObjKind;
|
|
begin
|
|
begin
|
|
@@ -4392,26 +4461,19 @@ begin
|
|
Engine.FinishScope(stTypeDef,ArrEl);
|
|
Engine.FinishScope(stTypeDef,ArrEl);
|
|
end;
|
|
end;
|
|
tkprocedure,tkfunction:
|
|
tkprocedure,tkfunction:
|
|
- begin
|
|
|
|
- if CurToken=tkFunction then
|
|
|
|
|
|
+ ParseProcType(TypeName,NamePos,TypeParams,false);
|
|
|
|
+ tkIdentifier:
|
|
|
|
+ if CurTokenIsIdentifier('reference') then
|
|
begin
|
|
begin
|
|
- ProcTypeEl := CreateFunctionType(TypeName, 'Result', Parent, False,
|
|
|
|
- NamePos, TypeParams);
|
|
|
|
- ProcType:=ptFunction;
|
|
|
|
|
|
+ NextToken;
|
|
|
|
+ CheckToken(tkto);
|
|
|
|
+ NextToken;
|
|
|
|
+ ParseProcType(TypeName,NamePos,TypeParams,true);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
- begin
|
|
|
|
- ProcTypeEl := TPasProcedureType(CreateElement(TPasProcedureType,
|
|
|
|
- TypeName, Parent, visDefault, NamePos, TypeParams));
|
|
|
|
- ProcType:=ptProcedure;
|
|
|
|
- end;
|
|
|
|
- if AddToParent and (Parent is TPasDeclarations) then
|
|
|
|
- TPasDeclarations(Parent).Functions.Add(ProcTypeEl);
|
|
|
|
- InitGenericType(ProcTypeEl,TypeParams);
|
|
|
|
- ParseProcedureOrFunction(ProcTypeEl, ProcTypeEl, ProcType, True);
|
|
|
|
- end;
|
|
|
|
|
|
+ ParseExcTypeParamsNotAllowed;
|
|
else
|
|
else
|
|
- ParseTypeParamsNotAllowed;
|
|
|
|
|
|
+ ParseExcTypeParamsNotAllowed;
|
|
end;
|
|
end;
|
|
finally
|
|
finally
|
|
for i:=0 to TypeParams.Count-1 do
|
|
for i:=0 to TypeParams.Count-1 do
|
|
@@ -4539,7 +4601,10 @@ begin
|
|
while CurToken=tkSquaredBraceOpen do
|
|
while CurToken=tkSquaredBraceOpen do
|
|
begin
|
|
begin
|
|
if msPrefixedAttributes in CurrentModeswitches then
|
|
if msPrefixedAttributes in CurrentModeswitches then
|
|
- VarList.Add(ParseAttributes(Parent))
|
|
|
|
|
|
+ begin
|
|
|
|
+ VarList.Add(ParseAttributes(Parent,false));
|
|
|
|
+ NextToken;
|
|
|
|
+ end
|
|
else
|
|
else
|
|
CheckToken(tkIdentifier);
|
|
CheckToken(tkIdentifier);
|
|
end;
|
|
end;
|
|
@@ -6343,6 +6408,7 @@ function TPasParser.ParseProcedureOrFunctionDecl(Parent: TPasElement;
|
|
): TPasProcedure;
|
|
): TPasProcedure;
|
|
var
|
|
var
|
|
NameParts: TProcedureNameParts;
|
|
NameParts: TProcedureNameParts;
|
|
|
|
+ NamePos: TPasSourcePos;
|
|
|
|
|
|
function ExpectProcName: string;
|
|
function ExpectProcName: string;
|
|
{ Simple procedure:
|
|
{ Simple procedure:
|
|
@@ -6366,6 +6432,7 @@ var
|
|
Part: TProcedureNamePart;
|
|
Part: TProcedureNamePart;
|
|
begin
|
|
begin
|
|
Result:=ExpectIdentifier;
|
|
Result:=ExpectIdentifier;
|
|
|
|
+ NamePos:=CurSourcePos;
|
|
Cnt:=1;
|
|
Cnt:=1;
|
|
repeat
|
|
repeat
|
|
NextToken;
|
|
NextToken;
|
|
@@ -6375,6 +6442,7 @@ var
|
|
begin
|
|
begin
|
|
inc(Cnt);
|
|
inc(Cnt);
|
|
CurName:=ExpectIdentifier;
|
|
CurName:=ExpectIdentifier;
|
|
|
|
+ NamePos:=CurSourcePos;
|
|
Result:=Result+'.'+CurName;
|
|
Result:=Result+'.'+CurName;
|
|
if NameParts<>nil then
|
|
if NameParts<>nil then
|
|
begin
|
|
begin
|
|
@@ -6424,6 +6492,8 @@ var
|
|
else
|
|
else
|
|
break;
|
|
break;
|
|
until false;
|
|
until false;
|
|
|
|
+ if (NameParts=nil) and MustBeGeneric then
|
|
|
|
+ CheckToken(tkLessThan);
|
|
UngetToken;
|
|
UngetToken;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -6452,12 +6522,14 @@ begin
|
|
if (ot=otUnknown) then
|
|
if (ot=otUnknown) then
|
|
ParseExc(nErrUnknownOperatorType,SErrUnknownOperatorType,[CurTokenString]);
|
|
ParseExc(nErrUnknownOperatorType,SErrUnknownOperatorType,[CurTokenString]);
|
|
Name:=OperatorNames[Ot];
|
|
Name:=OperatorNames[Ot];
|
|
|
|
+ NamePos:=CurTokenPos;
|
|
end;
|
|
end;
|
|
ptAnonymousProcedure,ptAnonymousFunction:
|
|
ptAnonymousProcedure,ptAnonymousFunction:
|
|
begin
|
|
begin
|
|
Name:='';
|
|
Name:='';
|
|
if MustBeGeneric then
|
|
if MustBeGeneric then
|
|
ParseExcTokenError('generic'); // inconsistency
|
|
ParseExcTokenError('generic'); // inconsistency
|
|
|
|
+ NamePos:=CurTokenPos;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
Name:=ExpectProcName;
|
|
Name:=ExpectProcName;
|
|
@@ -6466,7 +6538,7 @@ begin
|
|
if Name<>'' then
|
|
if Name<>'' then
|
|
Parent:=CheckIfOverLoaded(Parent,Name);
|
|
Parent:=CheckIfOverLoaded(Parent,Name);
|
|
Result := TPasProcedure(Engine.CreateElement(PC, Name, Parent, AVisibility,
|
|
Result := TPasProcedure(Engine.CreateElement(PC, Name, Parent, AVisibility,
|
|
- CurSourcePos, NameParts));
|
|
|
|
|
|
+ NamePos, NameParts));
|
|
if NameParts<>nil then
|
|
if NameParts<>nil then
|
|
begin
|
|
begin
|
|
if Result.NameParts=nil then
|
|
if Result.NameParts=nil then
|
|
@@ -6623,7 +6695,6 @@ Var
|
|
NamePos: TPasSourcePos;
|
|
NamePos: TPasSourcePos;
|
|
OldCount, i: Integer;
|
|
OldCount, i: Integer;
|
|
CurEl: TPasElement;
|
|
CurEl: TPasElement;
|
|
- Attr: TPasAttributes;
|
|
|
|
LastToken: TToken;
|
|
LastToken: TToken;
|
|
begin
|
|
begin
|
|
if AllowMethods then
|
|
if AllowMethods then
|
|
@@ -6736,11 +6807,7 @@ begin
|
|
end;
|
|
end;
|
|
tkSquaredBraceOpen:
|
|
tkSquaredBraceOpen:
|
|
if msPrefixedAttributes in CurrentModeswitches then
|
|
if msPrefixedAttributes in CurrentModeswitches then
|
|
- begin
|
|
|
|
- Attr:=ParseAttributes(ARec);
|
|
|
|
- ARec.Members.Add(Attr);
|
|
|
|
- Engine.FinishScope(stDeclaration,Attr);
|
|
|
|
- end
|
|
|
|
|
|
+ ParseAttributes(ARec,true)
|
|
else
|
|
else
|
|
CheckToken(tkIdentifier);
|
|
CheckToken(tkIdentifier);
|
|
tkCase :
|
|
tkCase :
|
|
@@ -6854,14 +6921,15 @@ begin
|
|
ParseExc(nParserExpectVisibility,SParserExpectVisibility);
|
|
ParseExc(nParserExpectVisibility,SParserExpectVisibility);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TPasParser.ProcessMethod(AType: TPasClassType; IsClass : Boolean; AVisibility : TPasMemberVisibility);
|
|
|
|
|
|
+procedure TPasParser.ProcessMethod(AType: TPasClassType; IsClass: Boolean;
|
|
|
|
+ AVisibility: TPasMemberVisibility; MustBeGeneric: boolean);
|
|
|
|
|
|
var
|
|
var
|
|
Proc: TPasProcedure;
|
|
Proc: TPasProcedure;
|
|
ProcType: TProcType;
|
|
ProcType: TProcType;
|
|
begin
|
|
begin
|
|
ProcType:=GetProcTypeFromToken(CurToken,isClass);
|
|
ProcType:=GetProcTypeFromToken(CurToken,isClass);
|
|
- Proc:=ParseProcedureOrFunctionDecl(AType,ProcType,false,AVisibility);
|
|
|
|
|
|
+ Proc:=ParseProcedureOrFunctionDecl(AType,ProcType,MustBeGeneric,AVisibility);
|
|
if Proc.Parent is TPasOverloadedProc then
|
|
if Proc.Parent is TPasOverloadedProc then
|
|
TPasOverloadedProc(Proc.Parent).Overloads.Add(Proc)
|
|
TPasOverloadedProc(Proc.Parent).Overloads.Add(Proc)
|
|
else
|
|
else
|
|
@@ -6918,14 +6986,41 @@ Var
|
|
T : TPasType;
|
|
T : TPasType;
|
|
Done : Boolean;
|
|
Done : Boolean;
|
|
begin
|
|
begin
|
|
- // Writeln('Parsing local types');
|
|
|
|
|
|
+ //Writeln('Parsing local types');
|
|
|
|
+ while (CurToken=tkSquaredBraceOpen)
|
|
|
|
+ and (msPrefixedAttributes in CurrentModeswitches) do
|
|
|
|
+ begin
|
|
|
|
+ ParseAttributes(AType,true);
|
|
|
|
+ NextToken;
|
|
|
|
+ end;
|
|
Repeat
|
|
Repeat
|
|
T:=ParseTypeDecl(AType);
|
|
T:=ParseTypeDecl(AType);
|
|
T.Visibility:=AVisibility;
|
|
T.Visibility:=AVisibility;
|
|
AType.Members.Add(t);
|
|
AType.Members.Add(t);
|
|
// Writeln(CurtokenString,' ',TokenInfos[Curtoken]);
|
|
// Writeln(CurtokenString,' ',TokenInfos[Curtoken]);
|
|
NextToken;
|
|
NextToken;
|
|
- Done:=(Curtoken<>tkIdentifier) or CheckVisibility(CurTokenString,AVisibility);
|
|
|
|
|
|
+ case CurToken of
|
|
|
|
+ tkgeneric:
|
|
|
|
+ begin
|
|
|
|
+ NextToken;
|
|
|
|
+ if CurToken<>tkIdentifier then
|
|
|
|
+ Done:=true;
|
|
|
|
+ UngetToken;
|
|
|
|
+ end;
|
|
|
|
+ tkIdentifier:
|
|
|
|
+ Done:=CheckVisibility(CurTokenString,AVisibility);
|
|
|
|
+ tkSquaredBraceOpen:
|
|
|
|
+ if msPrefixedAttributes in CurrentModeswitches then
|
|
|
|
+ repeat
|
|
|
|
+ ParseAttributes(AType,true);
|
|
|
|
+ NextToken;
|
|
|
|
+ Done:=false;
|
|
|
|
+ until CurToken<>tkSquaredBraceOpen
|
|
|
|
+ else
|
|
|
|
+ Done:=true;
|
|
|
|
+ else
|
|
|
|
+ Done:=true;
|
|
|
|
+ end;
|
|
if Done then
|
|
if Done then
|
|
UngetToken;
|
|
UngetToken;
|
|
Until Done;
|
|
Until Done;
|
|
@@ -6940,6 +7035,12 @@ Var
|
|
Done : Boolean;
|
|
Done : Boolean;
|
|
begin
|
|
begin
|
|
// Writeln('Parsing local consts');
|
|
// Writeln('Parsing local consts');
|
|
|
|
+ while (CurToken=tkSquaredBraceOpen)
|
|
|
|
+ and (msPrefixedAttributes in CurrentModeswitches) do
|
|
|
|
+ begin
|
|
|
|
+ ParseAttributes(AType,true);
|
|
|
|
+ NextToken;
|
|
|
|
+ end;
|
|
Repeat
|
|
Repeat
|
|
C:=ParseConstDecl(AType);
|
|
C:=ParseConstDecl(AType);
|
|
C.Visibility:=AVisibility;
|
|
C.Visibility:=AVisibility;
|
|
@@ -6950,17 +7051,29 @@ begin
|
|
if CurToken<>tkSemicolon then
|
|
if CurToken<>tkSemicolon then
|
|
exit;
|
|
exit;
|
|
NextToken;
|
|
NextToken;
|
|
- Done:=(CurToken<>tkIdentifier) or CheckVisibility(CurTokenString,AVisibility);
|
|
|
|
|
|
+ case CurToken of
|
|
|
|
+ tkIdentifier:
|
|
|
|
+ Done:=CheckVisibility(CurTokenString,AVisibility);
|
|
|
|
+ tkSquaredBraceOpen:
|
|
|
|
+ if msPrefixedAttributes in CurrentModeswitches then
|
|
|
|
+ repeat
|
|
|
|
+ ParseAttributes(AType,true);
|
|
|
|
+ NextToken;
|
|
|
|
+ Done:=false;
|
|
|
|
+ until CurToken<>tkSquaredBraceOpen
|
|
|
|
+ else
|
|
|
|
+ Done:=true;
|
|
|
|
+ else
|
|
|
|
+ Done:=true;
|
|
|
|
+ end;
|
|
if Done then
|
|
if Done then
|
|
UngetToken;
|
|
UngetToken;
|
|
Until Done;
|
|
Until Done;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TPasParser.ParseClassMembers(AType: TPasClassType);
|
|
procedure TPasParser.ParseClassMembers(AType: TPasClassType);
|
|
-
|
|
|
|
Type
|
|
Type
|
|
TSectionType = (stNone,stConst,stType,stVar,stClassVar);
|
|
TSectionType = (stNone,stConst,stType,stVar,stClassVar);
|
|
-
|
|
|
|
Var
|
|
Var
|
|
CurVisibility : TPasMemberVisibility;
|
|
CurVisibility : TPasMemberVisibility;
|
|
CurSection : TSectionType;
|
|
CurSection : TSectionType;
|
|
@@ -6969,7 +7082,6 @@ Var
|
|
LastToken: TToken;
|
|
LastToken: TToken;
|
|
PropEl: TPasProperty;
|
|
PropEl: TPasProperty;
|
|
MethodRes: TPasMethodResolution;
|
|
MethodRes: TPasMethodResolution;
|
|
- Attr: TPasAttributes;
|
|
|
|
begin
|
|
begin
|
|
CurSection:=stNone;
|
|
CurSection:=stNone;
|
|
haveClass:=false;
|
|
haveClass:=false;
|
|
@@ -6982,160 +7094,186 @@ begin
|
|
begin
|
|
begin
|
|
//writeln('TPasParser.ParseClassMembers LastToken=',LastToken,' CurToken=',CurToken,' haveClass=',haveClass,' CurSection=',CurSection);
|
|
//writeln('TPasParser.ParseClassMembers LastToken=',LastToken,' CurToken=',CurToken,' haveClass=',haveClass,' CurSection=',CurSection);
|
|
case CurToken of
|
|
case CurToken of
|
|
- tkType:
|
|
|
|
|
|
+ tkType:
|
|
|
|
+ begin
|
|
|
|
+ if haveClass then
|
|
|
|
+ ParseExcExpectedAorB('Procedure','Function');
|
|
|
|
+ case AType.ObjKind of
|
|
|
|
+ okClass,okObject,
|
|
|
|
+ okClassHelper,okRecordHelper,okTypeHelper: ;
|
|
|
|
+ else
|
|
|
|
+ ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['TYPE',ObjKindNames[AType.ObjKind]]);
|
|
|
|
+ end;
|
|
|
|
+ CurSection:=stType;
|
|
|
|
+ NextToken;
|
|
|
|
+ ParseMembersLocalTypes(AType,CurVisibility);
|
|
|
|
+ CurSection:=stNone;
|
|
|
|
+ end;
|
|
|
|
+ tkConst:
|
|
|
|
+ begin
|
|
|
|
+ if haveClass then
|
|
|
|
+ ParseExcExpectedAorB('Procedure','Var');
|
|
|
|
+ case AType.ObjKind of
|
|
|
|
+ okClass,okObject,
|
|
|
|
+ okClassHelper,okRecordHelper,okTypeHelper: ;
|
|
|
|
+ else
|
|
|
|
+ ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['CONST',ObjKindNames[AType.ObjKind]]);
|
|
|
|
+ end;
|
|
|
|
+ CurSection:=stConst;
|
|
|
|
+ NextToken;
|
|
|
|
+ ParseMembersLocalConsts(AType,CurVisibility);
|
|
|
|
+ CurSection:=stNone;
|
|
|
|
+ end;
|
|
|
|
+ tkVar:
|
|
|
|
+ if not (CurSection in [stVar,stClassVar]) then
|
|
begin
|
|
begin
|
|
- case AType.ObjKind of
|
|
|
|
- okClass,okObject,
|
|
|
|
- okClassHelper,okRecordHelper,okTypeHelper: ;
|
|
|
|
|
|
+ if (AType.ObjKind in okWithFields)
|
|
|
|
+ or (haveClass and (AType.ObjKind in okAllHelpers)) then
|
|
|
|
+ // ok
|
|
else
|
|
else
|
|
- ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['TYPE',ObjKindNames[AType.ObjKind]]);
|
|
|
|
- end;
|
|
|
|
- CurSection:=stType;
|
|
|
|
|
|
+ ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['VAR',ObjKindNames[AType.ObjKind]]);
|
|
|
|
+ if LastToken=tkClass then
|
|
|
|
+ CurSection:=stClassVar
|
|
|
|
+ else
|
|
|
|
+ CurSection:=stVar;
|
|
end;
|
|
end;
|
|
- tkConst:
|
|
|
|
|
|
+ tkIdentifier:
|
|
|
|
+ if CheckVisibility(CurTokenString,CurVisibility) then
|
|
|
|
+ CurSection:=stNone
|
|
|
|
+ else
|
|
begin
|
|
begin
|
|
if haveClass then
|
|
if haveClass then
|
|
- ParseExc(nParserExpectToken2Error,SParserExpectToken2Error,
|
|
|
|
- ['Procedure','Var']);
|
|
|
|
- case AType.ObjKind of
|
|
|
|
- okClass,okObject,
|
|
|
|
- okClassHelper,okRecordHelper,okTypeHelper: ;
|
|
|
|
- else
|
|
|
|
- ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['CONST',ObjKindNames[AType.ObjKind]]);
|
|
|
|
- end;
|
|
|
|
- CurSection:=stConst;
|
|
|
|
- end;
|
|
|
|
- tkVar:
|
|
|
|
- if not (CurSection in [stVar,stClassVar]) then
|
|
|
|
begin
|
|
begin
|
|
- if (AType.ObjKind in okWithFields)
|
|
|
|
- or (haveClass and (AType.ObjKind in okAllHelpers)) then
|
|
|
|
- // ok
|
|
|
|
- else
|
|
|
|
- ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['VAR',ObjKindNames[AType.ObjKind]]);
|
|
|
|
- if LastToken=tkClass then
|
|
|
|
- CurSection:=stClassVar
|
|
|
|
- else
|
|
|
|
- CurSection:=stVar;
|
|
|
|
- end;
|
|
|
|
- tkIdentifier:
|
|
|
|
- if CheckVisibility(CurtokenString,CurVisibility) then
|
|
|
|
- CurSection:=stNone
|
|
|
|
|
|
+ if LastToken=tkclass then
|
|
|
|
+ ParseExcExpectedAorB('Procedure','Function');
|
|
|
|
+ end
|
|
else
|
|
else
|
|
|
|
+ SaveComments;
|
|
|
|
+ Case CurSection of
|
|
|
|
+ stNone,
|
|
|
|
+ stVar:
|
|
begin
|
|
begin
|
|
- if haveClass then
|
|
|
|
- begin
|
|
|
|
- if LastToken=tkclass then
|
|
|
|
- ParseExcTokenError('procedure or function');
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- SaveComments;
|
|
|
|
- Case CurSection of
|
|
|
|
- stType:
|
|
|
|
- ParseMembersLocalTypes(AType,CurVisibility);
|
|
|
|
- stConst :
|
|
|
|
- ParseMembersLocalConsts(AType,CurVisibility);
|
|
|
|
- stNone,
|
|
|
|
- stVar:
|
|
|
|
- begin
|
|
|
|
- if not (AType.ObjKind in okWithFields) then
|
|
|
|
- ParseExc(nParserNoFieldsAllowed,SParserNoFieldsAllowedInX,[ObjKindNames[AType.ObjKind]]);
|
|
|
|
- ParseClassFields(AType,CurVisibility,CurSection=stClassVar);
|
|
|
|
- HaveClass:=False;
|
|
|
|
- end;
|
|
|
|
- stClassVar:
|
|
|
|
- begin
|
|
|
|
- if not (AType.ObjKind in okWithClassFields) then
|
|
|
|
- ParseExc(nParserNoFieldsAllowed,SParserNoFieldsAllowedInX,[ObjKindNames[AType.ObjKind]]);
|
|
|
|
- ParseClassFields(AType,CurVisibility,CurSection=stClassVar);
|
|
|
|
- HaveClass:=False;
|
|
|
|
- end;
|
|
|
|
- else
|
|
|
|
- Raise Exception.Create('Internal error 201704251415');
|
|
|
|
|
|
+ if not (AType.ObjKind in okWithFields) then
|
|
|
|
+ ParseExc(nParserNoFieldsAllowed,SParserNoFieldsAllowedInX,[ObjKindNames[AType.ObjKind]]);
|
|
|
|
+ ParseClassFields(AType,CurVisibility,CurSection=stClassVar);
|
|
|
|
+ HaveClass:=False;
|
|
end;
|
|
end;
|
|
- end;
|
|
|
|
- tkConstructor,tkDestructor:
|
|
|
|
- begin
|
|
|
|
- curSection:=stNone;
|
|
|
|
- if not haveClass then
|
|
|
|
- SaveComments;
|
|
|
|
- case AType.ObjKind of
|
|
|
|
- okObject,okClass: ;
|
|
|
|
- okClassHelper,okTypeHelper,okRecordHelper:
|
|
|
|
|
|
+ stClassVar:
|
|
begin
|
|
begin
|
|
- if (CurToken=tkdestructor) and not haveClass then
|
|
|
|
- ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['destructor',ObjKindNames[AType.ObjKind]]);
|
|
|
|
|
|
+ if not (AType.ObjKind in okWithClassFields) then
|
|
|
|
+ ParseExc(nParserNoFieldsAllowed,SParserNoFieldsAllowedInX,[ObjKindNames[AType.ObjKind]]);
|
|
|
|
+ ParseClassFields(AType,CurVisibility,CurSection=stClassVar);
|
|
|
|
+ HaveClass:=False;
|
|
end;
|
|
end;
|
|
else
|
|
else
|
|
- if CurToken=tkconstructor then
|
|
|
|
- ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['constructor',ObjKindNames[AType.ObjKind]])
|
|
|
|
- else
|
|
|
|
- ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['destructor',ObjKindNames[AType.ObjKind]]);
|
|
|
|
|
|
+ Raise Exception.Create('Internal error 201704251415');
|
|
end;
|
|
end;
|
|
- ProcessMethod(AType,HaveClass,CurVisibility);
|
|
|
|
- haveClass:=False;
|
|
|
|
end;
|
|
end;
|
|
- tkProcedure,tkFunction:
|
|
|
|
|
|
+ tkConstructor,tkDestructor:
|
|
|
|
+ begin
|
|
|
|
+ curSection:=stNone;
|
|
|
|
+ if not haveClass then
|
|
|
|
+ SaveComments;
|
|
|
|
+ case AType.ObjKind of
|
|
|
|
+ okObject,okClass: ;
|
|
|
|
+ okClassHelper,okTypeHelper,okRecordHelper:
|
|
|
|
+ begin
|
|
|
|
+ if (CurToken=tkdestructor) and not haveClass then
|
|
|
|
+ ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['destructor',ObjKindNames[AType.ObjKind]]);
|
|
|
|
+ end;
|
|
|
|
+ else
|
|
|
|
+ if CurToken=tkconstructor then
|
|
|
|
+ ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['constructor',ObjKindNames[AType.ObjKind]])
|
|
|
|
+ else
|
|
|
|
+ ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['destructor',ObjKindNames[AType.ObjKind]]);
|
|
|
|
+ end;
|
|
|
|
+ ProcessMethod(AType,HaveClass,CurVisibility,false);
|
|
|
|
+ haveClass:=False;
|
|
|
|
+ end;
|
|
|
|
+ tkProcedure,tkFunction:
|
|
|
|
+ begin
|
|
|
|
+ curSection:=stNone;
|
|
|
|
+ IsMethodResolution:=false;
|
|
|
|
+ if not haveClass then
|
|
begin
|
|
begin
|
|
- curSection:=stNone;
|
|
|
|
- IsMethodResolution:=false;
|
|
|
|
- if not haveClass then
|
|
|
|
|
|
+ SaveComments;
|
|
|
|
+ if AType.ObjKind=okClass then
|
|
begin
|
|
begin
|
|
- SaveComments;
|
|
|
|
- if AType.ObjKind=okClass then
|
|
|
|
|
|
+ NextToken;
|
|
|
|
+ if CurToken=tkIdentifier then
|
|
begin
|
|
begin
|
|
NextToken;
|
|
NextToken;
|
|
- if CurToken=tkIdentifier then
|
|
|
|
- begin
|
|
|
|
- NextToken;
|
|
|
|
- IsMethodResolution:=CurToken=tkDot;
|
|
|
|
- UngetToken;
|
|
|
|
- end;
|
|
|
|
|
|
+ IsMethodResolution:=CurToken=tkDot;
|
|
UngetToken;
|
|
UngetToken;
|
|
end;
|
|
end;
|
|
|
|
+ UngetToken;
|
|
end;
|
|
end;
|
|
- if IsMethodResolution then
|
|
|
|
- begin
|
|
|
|
- MethodRes:=ParseMethodResolution(AType);
|
|
|
|
- AType.Members.Add(MethodRes);
|
|
|
|
- Engine.FinishScope(stDeclaration,MethodRes);
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- ProcessMethod(AType,HaveClass,CurVisibility);
|
|
|
|
- haveClass:=False;
|
|
|
|
end;
|
|
end;
|
|
- tkclass:
|
|
|
|
|
|
+ if IsMethodResolution then
|
|
begin
|
|
begin
|
|
- case AType.ObjKind of
|
|
|
|
- okClass,okObject,
|
|
|
|
- okClassHelper,okRecordHelper,okTypeHelper: ;
|
|
|
|
- else
|
|
|
|
- ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['CLASS',ObjKindNames[AType.ObjKind]]);
|
|
|
|
- end;
|
|
|
|
- SaveComments;
|
|
|
|
- HaveClass:=True;
|
|
|
|
- curSection:=stNone;
|
|
|
|
- end;
|
|
|
|
- tkProperty:
|
|
|
|
|
|
+ MethodRes:=ParseMethodResolution(AType);
|
|
|
|
+ AType.Members.Add(MethodRes);
|
|
|
|
+ Engine.FinishScope(stDeclaration,MethodRes);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ ProcessMethod(AType,HaveClass,CurVisibility,false);
|
|
|
|
+ haveClass:=False;
|
|
|
|
+ end;
|
|
|
|
+ tkgeneric:
|
|
|
|
+ begin
|
|
|
|
+ if msDelphi in CurrentModeswitches then
|
|
|
|
+ ParseExcSyntaxError; // inconsistency, tkGeneric should be in Scanner.NonTokens
|
|
|
|
+ if haveClass and (LastToken=tkclass) then
|
|
|
|
+ ParseExcTokenError('Generic Class');
|
|
|
|
+ case AType.ObjKind of
|
|
|
|
+ okClass,okObject,
|
|
|
|
+ okClassHelper,okRecordHelper,okTypeHelper: ;
|
|
|
|
+ else
|
|
|
|
+ ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['generic',ObjKindNames[AType.ObjKind]]);
|
|
|
|
+ end;
|
|
|
|
+ SaveComments;
|
|
|
|
+ CurSection:=stNone;
|
|
|
|
+ NextToken;
|
|
|
|
+ if CurToken=tkclass then
|
|
begin
|
|
begin
|
|
- curSection:=stNone;
|
|
|
|
- if not haveClass then
|
|
|
|
- SaveComments;
|
|
|
|
- ExpectIdentifier;
|
|
|
|
- PropEl:=ParseProperty(AType,CurtokenString,CurVisibility,HaveClass);
|
|
|
|
- AType.Members.Add(PropEl);
|
|
|
|
- Engine.FinishScope(stDeclaration,PropEl);
|
|
|
|
- HaveClass:=False;
|
|
|
|
- end;
|
|
|
|
- tkSquaredBraceOpen:
|
|
|
|
- if msPrefixedAttributes in CurrentModeswitches then
|
|
|
|
- begin
|
|
|
|
- Attr:=ParseAttributes(AType);
|
|
|
|
- AType.Members.Add(Attr);
|
|
|
|
- Engine.FinishScope(stDeclaration,Attr);
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- CheckToken(tkIdentifier);
|
|
|
|
|
|
+ haveClass:=true;
|
|
|
|
+ NextToken;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ haveClass:=false;
|
|
|
|
+ if not (CurToken in [tkprocedure,tkfunction]) then
|
|
|
|
+ ParseExcExpectedAorB('Procedure','Function');
|
|
|
|
+ ProcessMethod(AType,HaveClass,CurVisibility,true);
|
|
|
|
+ end;
|
|
|
|
+ tkclass:
|
|
|
|
+ begin
|
|
|
|
+ case AType.ObjKind of
|
|
|
|
+ okClass,okObject,
|
|
|
|
+ okClassHelper,okRecordHelper,okTypeHelper: ;
|
|
|
|
+ else
|
|
|
|
+ ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['CLASS',ObjKindNames[AType.ObjKind]]);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ SaveComments;
|
|
|
|
+ HaveClass:=True;
|
|
|
|
+ curSection:=stNone;
|
|
|
|
+ end;
|
|
|
|
+ tkProperty:
|
|
|
|
+ begin
|
|
|
|
+ curSection:=stNone;
|
|
|
|
+ if not haveClass then
|
|
|
|
+ SaveComments;
|
|
|
|
+ ExpectIdentifier;
|
|
|
|
+ PropEl:=ParseProperty(AType,CurtokenString,CurVisibility,HaveClass);
|
|
|
|
+ AType.Members.Add(PropEl);
|
|
|
|
+ Engine.FinishScope(stDeclaration,PropEl);
|
|
|
|
+ HaveClass:=False;
|
|
|
|
+ end;
|
|
|
|
+ tkSquaredBraceOpen:
|
|
|
|
+ if msPrefixedAttributes in CurrentModeswitches then
|
|
|
|
+ ParseAttributes(AType,true)
|
|
|
|
+ else
|
|
|
|
+ CheckToken(tkIdentifier);
|
|
else
|
|
else
|
|
CheckToken(tkIdentifier);
|
|
CheckToken(tkIdentifier);
|
|
end;
|
|
end;
|