* Parse operators better

git-svn-id: trunk@31226 -
This commit is contained in:
michael 2015-07-24 08:52:34 +00:00
parent 3d6a6512ad
commit e4cd8565ae
6 changed files with 424 additions and 153 deletions

View File

@ -65,6 +65,8 @@ resourcestring
SPasTreeOverloadedProcedure = 'overloaded procedure';
SPasTreeProcedure = 'procedure';
SPasTreeFunction = 'function';
SPasTreeOperator = 'operator';
SPasTreeClassOperator = 'class operator';
SPasTreeClassProcedure = 'class procedure';
SPasTreeClassFunction = 'class function';
SPasTreeClassConstructor = 'class constructor';
@ -765,14 +767,39 @@ type
end;
{ TPasOperator }
TOperatorType = (otUnknown,otImplicit,otExplicit,otMul,otPlus, otMinus, otDivision,otLessThan, otEqual,
otGreaterThan, otAssign,otNotEqual,otLessEqualThan,otGreaterEqualThan,otPower,
otSymmetricalDifference, otInc, otDec, otMod, otNegative, otPositive, otBitWiseOr, otDiv,
otLeftShift, otLogicalOr, otBitwiseAnd, otbitwiseXor,otLogicalAnd,otLogicalNot,otLogicalXor,
otRightShift);
TOperatorTypes = set of TOperatorType;
TPasOperator = class(TPasProcedure)
TPasOperator = class(TPasFunction)
private
FOperatorType: TOperatorType;
FTokenBased: Boolean;
public
Class Function OperatorTypeToToken(T : TOperatorType) : String;
Class Function OperatorTypeToOperatorName(T: TOperatorType) : String;
Class Function TokenToOperatorType(S : String) : TOperatorType;
Class Function NameToOperatorType(S : String) : TOperatorType;
Procedure CorrectName;
function ElementTypeName: string; override;
function TypeName: string; override;
function GetDeclaration (full : boolean) : string; override;
Property OperatorType : TOperatorType Read FOperatorType Write FOperatorType;
// True if the declaration was using a token instead of a
Property TokenBased : Boolean Read FTokenBased Write FTokenBased;
end;
Type
{ TPasClassOperator }
TPasClassOperator = class(TPasOperator)
function TypeName: string; override;
end;
{ TPasConstructor }
TPasConstructor = class(TPasProcedure)
@ -1184,6 +1211,22 @@ const
'@','^',
'.');
UnaryOperators = [otImplicit,otExplicit,otAssign,otNegative,otPositive];
OperatorTokens : Array[TOperatorType] of string
= ('','','','*','+','-','/','<','=',
'>',':=','<>','<=','>=','**',
'><','Inc','Dec','mod','-','+','Or','div',
'shl','or','and','xor','and','not','xor',
'shr');
OperatorNames : Array[TOperatorType] of string
= ('','implicit','explicit','multiply','add','subtract','divide','lessthan','equal',
'greaterthan','assign','notequal','lessthanequal','greaterthanequal','power',
'symmetricaldifference','inc','dec','modulus','negative','positive','bitwiseor','intdivide',
'leftshift','logicalor','bitwiseand','bitwisexor','logicaland','logicalnot','logicalxor',
'rightshift');
cPasMemberHint : array[TPasMemberHint] of string =
( 'deprecated', 'library', 'platform', 'experimental', 'unimplemented' );
cCallingConventions : array[TCallingConvention] of string =
@ -1199,6 +1242,13 @@ implementation
uses SysUtils;
{ TPasClassOperator }
function TPasClassOperator.TypeName: string;
begin
Result:='class operator';
end;
{ TPasImplAsmStatement }
constructor TPasImplAsmStatement.Create(const AName: string;
@ -1412,7 +1462,63 @@ begin
end;
function TPasClassFunction.ElementTypeName: string; begin Result := SPasTreeClassFunction; end;
function TPasOperator.ElementTypeName: string; begin Result := SPasTreeFunction end;
class function TPasOperator.OperatorTypeToToken(T: TOperatorType): String;
begin
Result:=OperatorTokens[T];
end;
class function TPasOperator.OperatorTypeToOperatorName(T: TOperatorType
): String;
begin
Result:=OperatorNames[T];
end;
class function TPasOperator.TokenToOperatorType(S: String): TOperatorType;
begin
Result:=High(TOperatorType);
While (Result>otUnknown) and (CompareText(S,OperatorTokens[Result])<>0) do
Result:=Pred(Result);
end;
class function TPasOperator.NameToOperatorType(S: String): TOperatorType;
begin
Result:=High(TOperatorType);
While (Result>otUnknown) and (CompareText(S,OperatorNames[Result])<>0) do
Result:=Pred(Result);
end;
procedure TPasOperator.CorrectName;
Var
I : Integer;
begin
I:=Pos('(',Name);
if I<>0 then
Name:=Copy(Name,1,I)
else
Name:=Name+'(';
if Assigned(ProcType) and Assigned(ProcType.Args) then
for i:=0 to ProcType.Args.Count-1 do
begin
if i>0 then
Name:=Name+',';
Name:=Name+TPasArgument(ProcType.Args[i]).ArgType.Name;
end;
if Assigned(TPasFunctionType(ProcType).ResultEl) and
Assigned(TPasFunctionType(ProcType).ResultEl.ResultType) then
Name:=Name+'):'+TPasFunctionType(ProcType).ResultEl.ResultType.Name;
end;
function TPasOperator.ElementTypeName: string;
begin
if self is TPasClassOperator then
Result := SPasTreeClassOperator
else
Result := SPasTreeOperator
end;
function TPasConstructor.ElementTypeName: string; begin Result := SPasTreeConstructor end;
function TPasDestructor.ElementTypeName: string; begin Result := SPasTreeDestructor end;
function TPasProcedureImpl.ElementTypeName: string; begin Result := SPasTreeProcedureImpl end;
@ -2968,6 +3074,7 @@ begin
end;
GetModifiers(S);
Result:=IndentStrings(S,Length(S[0]));
finally
S.Free;
end;

View File

@ -38,6 +38,7 @@ resourcestring
SParserExpectedCommaSemicolon = 'Expected "," or ";"';
SParserExpectedAssignIn = 'Expected := or in';
SParserExpectedCommaColon = 'Expected "," or ":"';
SErrUnknownOperatorType = 'Unknown operator type: %s';
SParserOnlyOneArgumentCanHaveDefault = 'A default value can only be assigned to 1 parameter';
SParserExpectedLBracketColon = 'Expected "(" or ":"';
SParserExpectedLBracketSemicolon = 'Expected "(" or ";"';
@ -119,7 +120,7 @@ type
property Column: Integer read FColumn;
end;
TProcType = (ptProcedure, ptFunction, ptOperator, ptConstructor, ptDestructor,
TProcType = (ptProcedure, ptFunction, ptOperator, ptClassOperator, ptConstructor, ptDestructor,
ptClassProcedure, ptClassFunction, ptClassConstructor, ptClassDestructor);
@ -175,6 +176,7 @@ type
function CheckProcedureArgs(Parent: TPasElement; Args: TFPList; Mandatory: Boolean): boolean;
function CheckVisibility(S: String; var AVisibility: TPasMemberVisibility): Boolean;
procedure ParseExc(const Msg: String);
procedure ParseExc(const Fmt: String; Args : Array of const);
function OpLevel(t: TToken): Integer;
Function TokenToExprOp (AToken : TToken) : TExprOpCode;
function CreateElement(AClass: TPTreeElement; const AName: String; AParent: TPasElement): TPasElement;overload;
@ -399,7 +401,7 @@ var
if (length(s)>2) then
case S[3] of
'c' : Scanner.Options:=Scanner.Options+[po_cassignments];
'd' : Parser.Options:=Parser.Options+[po_delphi];
'd','2' : Parser.Options:=Parser.Options+[po_delphi];
end;
end;
end else
@ -556,6 +558,11 @@ begin
Scanner.CurFilename, Scanner.CurRow, Scanner.CurColumn);
end;
procedure TPasParser.ParseExc(const Fmt: String; Args: array of const);
begin
ParseExc(Format(Fmt,Args));
end;
constructor TPasParser.Create(AScanner: TPascalScanner;
AFileResolver: TBaseFileResolver; AEngine: TPasTreeContainer);
begin
@ -1943,7 +1950,10 @@ begin
else
Result:=ptDestructor;
tkOperator:
Result:=ptOperator;
if IsClass then
Result:=ptClassOperator
else
Result:=ptOperator;
else
ParseExc(SParserNotAProcToken);
end;
@ -2867,24 +2877,21 @@ procedure TPasParser.ParseProcedureOrFunctionHeader(Parent: TPasElement;
Var
Tok : String;
i: Integer;
Proc: TPasProcedure;
CC : TCallingConvention;
PM : TProcedureModifier;
Done: Boolean;
begin
CheckProcedureArgs(Parent,Element.Args,ProcType=ptOperator);
// Element must be non-nil. Removed all checks for not-nil.
// If it is nil, the following fails anyway.
CheckProcedureArgs(Parent,Element.Args,ProcType in [ptOperator,ptClassOperator]);
case ProcType of
ptFunction,ptClassFunction:
begin
ExpectToken(tkColon);
if Assigned(Element) then // !!!
TPasFunctionType(Element).ResultEl.ResultType := ParseType(Parent)
else
ParseType(nil);
TPasFunctionType(Element).ResultEl.ResultType := ParseType(Parent)
end;
ptOperator:
ptOperator,ptClassOperator:
begin
NextToken;
if (CurToken=tkIdentifier) then
@ -2897,10 +2904,7 @@ begin
TPasFunctionType(Element).ResultEl.Name := 'Result'
else
ParseExc(SParserExpectedColonID);
if Assigned(Element) then // !!!
TPasFunctionType(Element).ResultEl.ResultType := ParseType(Parent)
else
ParseType(nil);
TPasFunctionType(Element).ResultEl.ResultType := ParseType(Parent)
end;
end;
if OfObjectPossible then
@ -2934,16 +2938,20 @@ begin
NextToken;
If TokenisCallingConvention(CurTokenString,cc) then
begin
if Assigned(Element) then // !!!
Element.CallingConvention:=Cc;
Element.CallingConvention:=Cc;
if cc = ccSysCall then
begin
// remove LibBase
NextToken;
// remove legacy or basesysv on MorphOS syscalls
if CurTokenIsIdentifier('legacy') or CurTokenIsIdentifier('BaseSysV') then
NextToken;
NextToken; // remove offset
if CurToken=tkSemiColon then
UngetToken
else
// remove legacy or basesysv on MorphOS syscalls
begin
if CurTokenIsIdentifier('legacy') or CurTokenIsIdentifier('BaseSysV') then
NextToken;
NextToken; // remove offset
end;
end;
ExpectToken(tkSemicolon);
end
@ -2982,21 +2990,8 @@ begin
Until Done;
if DoCheckHint then // deprecated,platform,experimental,library, unimplemented etc
ConsumeSemi;
if (ProcType = ptOperator) and (Parent is TPasProcedure) then
begin
Proc:=TPasProcedure(Parent);
Proc.Name := Proc.Name + '(';
for i := 0 to Proc.ProcType.Args.Count - 1 do
begin
if i > 0 then
Proc.Name := Proc.Name + ', ';
Proc.Name := Proc.Name +
TPasArgument(Proc.ProcType.Args[i]).ArgType.Name;
end;
Proc.Name := Proc.Name + '): ' +
TPasFunctionType(Proc.ProcType).ResultEl.ResultType.Name;
end;
if (ProcType in [ptOperator,ptClassOperator]) and (Parent is TPasOperator) then
TPasOperator(Parent).CorrectName;
if (Parent is TPasProcedure)
and (not TPasProcedure(Parent).IsForward)
and (not TPasProcedure(Parent).IsExternal)
@ -3659,12 +3654,13 @@ begin
ptFunction : Result:=TPasFunction;
ptClassFunction : Result:=TPasClassFunction;
ptClassProcedure : Result:=TPasClassProcedure;
ptClassConstructor : Result:=TPasClassConstructor;
ptClassDestructor : Result:=TPasClassDestructor;
ptClassConstructor : Result:=TPasClassConstructor;
ptClassDestructor : Result:=TPasClassDestructor;
ptProcedure : Result:=TPasProcedure;
ptConstructor : Result:=TPasConstructor;
ptDestructor : Result:=TPasDestructor;
ptOperator : Result:=TPasOperator;
ptClassOperator : Result:=TPasClassOperator;
else
ParseExc('Unknown procedure Type '+intToStr(Ord(ProcType)));
end;
@ -3690,28 +3686,60 @@ function TPasParser.ParseProcedureOrFunctionDecl(Parent: TPasElement; ProcType:
var
Name: String;
PC : TPTreeElement;
Ot : TOperatorType;
IsTokenBased : Boolean;
begin
If (ProcType<>ptOperator) then
If (Not (ProcType in [ptOperator,ptClassOperator])) then
Name:=ExpectProcName
else
begin
NextToken;
Name := 'operator ' + TokenInfos[CurToken];
IsTokenBased:=Curtoken<>tkIdentifier;
if IsTokenBased then
OT:=TPasOperator.TokenToOperatorType(CurTokenText)
else
OT:=TPasOperator.NameToOperatorType(CurTokenString);
if (ot=otUnknown) then
ParseExc(SErrUnknownOperatorType,[CurTokenString]);
Name:=OperatorNames[Ot];
end;
PC:=GetProcedureClass(ProcType);
Parent:=CheckIfOverLoaded(Parent,Name);
Result:=TPasProcedure(CreateElement(PC,Name,Parent,AVisibility));
try
if ProcType in [ptFunction, ptClassFunction] then
Result.ProcType := CreateFunctionType('', 'Result', Result, True)
else if ProcType=ptOperator then
Result.ProcType := CreateFunctionType('', '__INVALID__', Result,True)
if Not (ProcType in [ptFunction, ptClassFunction, ptOperator, ptClassOperator]) then
Result.ProcType := TPasProcedureType(CreateElement(TPasProcedureType, '', Result))
else
Result.ProcType := TPasProcedureType(CreateElement(TPasProcedureType, '', Result));
begin
Result.ProcType := CreateFunctionType('', 'Result', Result, True);
if (ProcType in [ptOperator, ptClassOperator]) then
begin
TPasOperator(Result).TokenBased:=IsTokenBased;
TPasOperator(Result).OperatorType:=OT;
TPasOperator(Result).CorrectName;
end;
end;
ParseProcedureOrFunctionHeader(Result, Result.ProcType, ProcType, False);
Result.Hints:=Result.ProcType.Hints;
Result.HintMessage:=Result.ProcType.HintMessage
Result.HintMessage:=Result.ProcType.HintMessage;
// + is detected as 'positive', but is in fact Add if there are 2 arguments.
if (ProcType in [ptOperator, ptClassOperator]) then
With TPasOperator(Result) do
begin
if (OperatorType in [otPositive, otNegative]) then
begin
if (ProcType.Args.Count>1) then
begin
Case OperatorType of
otPositive : OperatorType:=otPlus;
otNegative : OperatorType:=otMinus;
end;
Name:=OperatorNames[OperatorType];
TPasOperator(Result).CorrectName;
end;
end;
end;
except
FreeAndNil(Result);
Raise;
@ -3802,6 +3830,7 @@ begin
Prop.isClass:=isClass;
Arec.Members.Add(Prop);
end;
tkOperator,
tkProcedure,
tkFunction :
begin
@ -3848,10 +3877,10 @@ begin
else
ParseExc(SParserTypeSyntaxError);
end;
if CurToken<>AEndToken then
NextToken;
If CurToken<>tkClass then
isClass:=False;
if CurToken<>AEndToken then
NextToken;
end;
end;

View File

@ -43,6 +43,8 @@ Type
FUseImplementation: Boolean;
function GetPL: TPasLibrary;
function GetPP: TPasProgram;
procedure CleanupParser;
procedure SetupParser;
protected
procedure SetUp; override;
procedure TearDown; override;
@ -56,6 +58,7 @@ Type
Procedure StartParsing;
Procedure ParseDeclarations;
Procedure ParseModule;
procedure ResetParser;
Procedure CheckHint(AHint : TPasMemberHint);
Function AssertExpression(Const Msg: String; AExpr : TPasExpr; aKind : TPasExprKind; AClass : TClass) : TPasExpr;
Function AssertExpression(Const Msg: String; AExpr : TPasExpr; aKind : TPasExprKind; AValue : String) : TPrimitiveExpr;
@ -74,6 +77,7 @@ Type
Procedure AssertEquals(Const Msg : String; AExpected, AActual: TProcedureModifiers); overload;
Procedure AssertEquals(Const Msg : String; AExpected, AActual: TAssignKind); overload;
Procedure AssertEquals(Const Msg : String; AExpected, AActual: TProcedureMessageType); overload;
Procedure AssertEquals(Const Msg : String; AExpected, AActual: TOperatorType); overload;
Procedure HaveHint(AHint : TPasMemberHint; AHints : TPasMemberHints);
Property Resolver : TStreamResolver Read FResolver;
Property Scanner : TPascalScanner Read FScanner;
@ -148,7 +152,8 @@ begin
Result:=Module as TPasLibrary;
end;
procedure TTestParser.SetUp;
procedure TTestParser.SetupParser;
begin
FResolver:=TStreamResolver.Create;
FResolver.OwnsStreams:=True;
@ -163,7 +168,8 @@ begin
FIsUnit:=False;
end;
procedure TTestParser.TearDown;
procedure TTestParser.CleanupParser;
begin
if Not Assigned(FModule) then
FreeAndNil(FDeclarations)
@ -181,6 +187,25 @@ begin
FreeAndNil(FResolver);
end;
procedure TTestParser.ResetParser;
begin
CleanupParser;
SetupParser;
end;
procedure TTestParser.SetUp;
begin
Inherited;
SetupParser;
end;
procedure TTestParser.TearDown;
begin
CleanupParser;
Inherited;
end;
procedure TTestParser.StartUnit(AUnitName: String);
begin
FIsUnit:=True;
@ -492,6 +517,13 @@ begin
GetEnumName(TypeInfo(TProcedureMessageType),Ord(AActual)));
end;
procedure TTestParser.AssertEquals(const Msg: String; AExpected,
AActual: TOperatorType);
begin
AssertEquals(Msg,GetEnumName(TypeInfo(TOperatorType),Ord(AExpected)),
GetEnumName(TypeInfo(TOperatorType),Ord(AExpected)));
end;
procedure TTestParser.HaveHint(AHint: TPasMemberHint; AHints: TPasMemberHints);
begin
If not (AHint in AHints) then

View File

@ -17,6 +17,7 @@ type
FFunc: TPasFunction;
FHint: String;
FProc: TPasProcedure;
FOperator:TPasOperator;
procedure AddDeclaration(const ASource: string; const AHint: String='');
procedure AssertArg(ProcType: TPasProcedureType; AIndex: Integer;
AName: String; AAccess: TArgumentAccess; const TypeName: String;
@ -33,6 +34,7 @@ type
function ParseProcedure(const ASource: string; const AHint: String=''): TPasProcedure;
Procedure ParseFunction;
function ParseFunction(const ASource : String; AResult: string = ''; const AHint: String=''; CC : TCallingConvention = ccDefault): TPasProcedure;
Procedure ParseOperator;
protected
procedure SetUp; override;
procedure TearDown; override;
@ -156,6 +158,8 @@ type
Procedure TestFunctionCdeclExternalLibNameName;
Procedure TestProcedureCdeclExternalName;
Procedure TestFunctionCdeclExternalName;
Procedure TestOperatorTokens;
procedure TestOperatorNames;
end;
implementation
@ -199,7 +203,7 @@ begin
AssertComment;
end;
Procedure TTestProcedureFunction.ParseProcedure;
procedure TTestProcedureFunction.ParseProcedure;
begin
// Writeln(source.text);
@ -230,7 +234,19 @@ begin
AssertEquals('Correct function result type name',AResult,FuncType.ResultEl.ResultType.Name);
end;
Procedure TTestProcedureFunction.ParseFunction;
procedure TTestProcedureFunction.ParseOperator;
begin
// Writeln(source.text);
ParseDeclarations;
AssertEquals('One operator definition',1,Declarations.Functions.Count);
AssertEquals('First declaration is function declaration.',TPasOperator,TObject(Declarations.Functions[0]).ClassType);
FOperator:=TPasOperator(Declarations.Functions[0]);
Definition:=FOperator;
if (Hint<>'') then
CheckHint(TPasMemberHint(Getenumvalue(typeinfo(TPasMemberHint),'h'+Hint)));
end;
procedure TTestProcedureFunction.ParseFunction;
begin
// Writeln(source.text);
ParseDeclarations;
@ -367,13 +383,13 @@ begin
TestEmptyProcedure;
end;
Procedure TTestProcedureFunction.TestEmptyFunction;
procedure TTestProcedureFunction.TestEmptyFunction;
begin
ParseFunction('');
AssertFunc([],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestEmptyFunctionComment;
procedure TTestProcedureFunction.TestEmptyFunctionComment;
begin
AddComment:=True;
TestEmptyProcedure;
@ -385,7 +401,7 @@ begin
AssertProc([],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestEmptyFunctionDeprecated;
procedure TTestProcedureFunction.TestEmptyFunctionDeprecated;
begin
ParseFunction('','deprecated');
AssertFunc([],ccDefault,0);
@ -397,7 +413,7 @@ begin
AssertProc([],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestEmptyFunctionPlatform;
procedure TTestProcedureFunction.TestEmptyFunctionPlatform;
begin
ParseFunction('','platform');
AssertFunc([],ccDefault,0);
@ -409,7 +425,7 @@ begin
AssertProc([],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestEmptyFunctionExperimental;
procedure TTestProcedureFunction.TestEmptyFunctionExperimental;
begin
ParseFunction('','experimental');
AssertFunc([],ccDefault,0);
@ -421,7 +437,7 @@ begin
AssertProc([],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestEmptyFunctionUnimplemented;
procedure TTestProcedureFunction.TestEmptyFunctionUnimplemented;
begin
ParseFunction('','unimplemented');
AssertFunc([],ccDefault,0);
@ -437,7 +453,7 @@ begin
AssertArg(ProcType,0,'B',argDefault,'Integer','');
end;
Procedure TTestProcedureFunction.TestFunctionOneArg;
procedure TTestProcedureFunction.TestFunctionOneArg;
begin
ParseFunction('(B : Integer)');
AssertFunc([],ccDefault,1);
@ -451,7 +467,7 @@ begin
AssertArg(ProcType,0,'B',argVar,'Integer','');
end;
Procedure TTestProcedureFunction.TestFunctionOneVarArg;
procedure TTestProcedureFunction.TestFunctionOneVarArg;
begin
ParseFunction('(Var B : Integer)');
AssertFunc([],ccDefault,1);
@ -465,7 +481,7 @@ begin
AssertArg(ProcType,0,'B',argConst,'Integer','');
end;
Procedure TTestProcedureFunction.TestFunctionOneConstArg;
procedure TTestProcedureFunction.TestFunctionOneConstArg;
begin
ParseFunction('(Const B : Integer)');
AssertFunc([],ccDefault,1);
@ -479,7 +495,7 @@ begin
AssertArg(ProcType,0,'B',argOut,'Integer','');
end;
Procedure TTestProcedureFunction.TestFunctionOneOutArg;
procedure TTestProcedureFunction.TestFunctionOneOutArg;
begin
ParseFunction('(Out B : Integer)');
AssertFunc([],ccDefault,1);
@ -493,7 +509,7 @@ begin
AssertArg(ProcType,0,'B',argConstRef,'Integer','');
end;
Procedure TTestProcedureFunction.TestFunctionOneConstRefArg;
procedure TTestProcedureFunction.TestFunctionOneConstRefArg;
begin
ParseFunction('(ConstRef B : Integer)');
AssertFunc([],ccDefault,1);
@ -508,7 +524,7 @@ begin
AssertArg(ProcType,1,'C',argDefault,'Integer','');
end;
Procedure TTestProcedureFunction.TestFunctionTwoArgs;
procedure TTestProcedureFunction.TestFunctionTwoArgs;
begin
ParseFunction('(B,C : Integer)');
AssertFunc([],ccDefault,2);
@ -524,7 +540,7 @@ begin
AssertArg(ProcType,1,'C',argDefault,'Integer','');
end;
Procedure TTestProcedureFunction.TestFunctionTwoArgsSeparate;
procedure TTestProcedureFunction.TestFunctionTwoArgsSeparate;
begin
ParseFunction('(B : Integer;C : Integer)');
AssertFunc([],ccDefault,2);
@ -539,7 +555,7 @@ begin
AssertArg(ProcType,0,'B',argDefault,'Integer','1');
end;
Procedure TTestProcedureFunction.TestFunctionOneArgDefault;
procedure TTestProcedureFunction.TestFunctionOneArgDefault;
begin
ParseFunction('(B : Integer = 1)');
AssertFunc([],ccDefault,1);
@ -553,7 +569,7 @@ begin
AssertArg(ProcType,0,'B',argDefault,'MySet','[1, 2]');
end;
Procedure TTestProcedureFunction.TestFunctionOneArgDefaultSet;
procedure TTestProcedureFunction.TestFunctionOneArgDefaultSet;
begin
ParseFunction('(B : MySet = [1,2])');
AssertFunc([],ccDefault,1);
@ -567,7 +583,7 @@ begin
AssertArg(ProcType,0,'B',argDefault,'Integer','1 + 2');
end;
Procedure TTestProcedureFunction.TestFunctionOneArgDefaultExpr;
procedure TTestProcedureFunction.TestFunctionOneArgDefaultExpr;
begin
ParseFunction('(B : Integer = 1 + 2)');
AssertFunc([],ccDefault,1);
@ -582,7 +598,7 @@ begin
AssertArg(ProcType,1,'C',argDefault,'Integer','2');
end;
Procedure TTestProcedureFunction.TestFunctionTwoArgsDefault;
procedure TTestProcedureFunction.TestFunctionTwoArgsDefault;
begin
ParseFunction('(B : Integer = 1; C : Integer = 2)');
AssertFunc([],ccDefault,2);
@ -597,7 +613,7 @@ begin
AssertArg(ProcType,0,'B',argVar,'','');
end;
Procedure TTestProcedureFunction.TestFunctionOneUntypedVarArg;
procedure TTestProcedureFunction.TestFunctionOneUntypedVarArg;
begin
ParseFunction('(Var B)');
AssertFunc([],ccDefault,1);
@ -612,7 +628,7 @@ begin
AssertArg(ProcType,1,'C',argVar,'','');
end;
Procedure TTestProcedureFunction.TestFunctionTwoUntypedVarArgs;
procedure TTestProcedureFunction.TestFunctionTwoUntypedVarArgs;
begin
ParseFunction('(Var B; Var C)');
AssertFunc([],ccDefault,2);
@ -627,7 +643,7 @@ begin
AssertArg(ProcType,0,'B',argConst,'','');
end;
Procedure TTestProcedureFunction.TestFunctionOneUntypedConstArg;
procedure TTestProcedureFunction.TestFunctionOneUntypedConstArg;
begin
ParseFunction('(Const B)');
AssertFunc([],ccDefault,1);
@ -642,7 +658,7 @@ begin
AssertArg(ProcType,1,'C',argConst,'','');
end;
Procedure TTestProcedureFunction.TestFunctionTwoUntypedConstArgs;
procedure TTestProcedureFunction.TestFunctionTwoUntypedConstArgs;
begin
ParseFunction('(Const B; Const C)');
AssertFunc([],ccDefault,2);
@ -657,7 +673,7 @@ begin
AssertArrayArg(ProcType,0,'B',argDefault,'Integer');
end;
Procedure TTestProcedureFunction.TestFunctionOpenArrayArg;
procedure TTestProcedureFunction.TestFunctionOpenArrayArg;
begin
ParseFunction('(B : Array of Integer)');
AssertFunc([],ccDefault,1);
@ -672,7 +688,7 @@ begin
AssertArrayArg(ProcType,1,'C',argDefault,'Integer');
end;
Procedure TTestProcedureFunction.TestFunctionTwoOpenArrayArgs;
procedure TTestProcedureFunction.TestFunctionTwoOpenArrayArgs;
begin
ParseFunction('(B : Array of Integer;C : Array of Integer)');
AssertFunc([],ccDefault,2);
@ -687,7 +703,7 @@ begin
AssertArrayArg(ProcType,0,'B',argConst,'Integer');
end;
Procedure TTestProcedureFunction.TestFunctionConstOpenArrayArg;
procedure TTestProcedureFunction.TestFunctionConstOpenArrayArg;
begin
ParseFunction('(Const B : Array of Integer)');
AssertFunc([],ccDefault,1);
@ -701,7 +717,7 @@ begin
AssertArrayArg(ProcType,0,'B',argVar,'Integer');
end;
Procedure TTestProcedureFunction.TestFunctionVarOpenArrayArg;
procedure TTestProcedureFunction.TestFunctionVarOpenArrayArg;
begin
ParseFunction('(Var B : Array of Integer)');
AssertFunc([],ccDefault,1);
@ -715,7 +731,7 @@ begin
AssertArrayArg(ProcType,0,'B',argDefault,'');
end;
Procedure TTestProcedureFunction.TestFunctionArrayOfConstArg;
procedure TTestProcedureFunction.TestFunctionArrayOfConstArg;
begin
ParseFunction('(B : Array of Const)');
AssertFunc([],ccDefault,1);
@ -729,100 +745,100 @@ begin
AssertArrayArg(ProcType,0,'B',argConst,'');
end;
Procedure TTestProcedureFunction.TestFunctionConstArrayOfConstArg;
procedure TTestProcedureFunction.TestFunctionConstArrayOfConstArg;
begin
ParseFunction('(Const B : Array of Const)');
AssertFunc([],ccDefault,1);
AssertArrayArg(FuncType,0,'B',argConst,'');
end;
Procedure TTestProcedureFunction.TestProcedureCdecl;
procedure TTestProcedureFunction.TestProcedureCdecl;
begin
ParseProcedure('; cdecl');
AssertProc([],ccCdecl,0);
end;
Procedure TTestProcedureFunction.TestFunctionCdecl;
procedure TTestProcedureFunction.TestFunctionCdecl;
begin
ParseFunction('','','',ccCdecl);
AssertFunc([],ccCdecl,0);
end;
Procedure TTestProcedureFunction.TestProcedureCdeclDeprecated;
procedure TTestProcedureFunction.TestProcedureCdeclDeprecated;
begin
ParseProcedure('; cdecl;','deprecated');
AssertProc([],ccCdecl,0);
end;
Procedure TTestProcedureFunction.TestFunctionCdeclDeprecated;
procedure TTestProcedureFunction.TestFunctionCdeclDeprecated;
begin
ParseFunction('','','deprecated',ccCdecl);
AssertFunc([],ccCdecl,0);
end;
Procedure TTestProcedureFunction.TestProcedureSafeCall;
procedure TTestProcedureFunction.TestProcedureSafeCall;
begin
ParseProcedure('; safecall;','');
AssertProc([],ccSafeCall,0);
end;
Procedure TTestProcedureFunction.TestFunctionSafeCall;
procedure TTestProcedureFunction.TestFunctionSafeCall;
begin
ParseFunction('','','',ccSafecall);
AssertFunc([],ccSafecall,0);
end;
Procedure TTestProcedureFunction.TestProcedurePascal;
procedure TTestProcedureFunction.TestProcedurePascal;
begin
ParseProcedure('; pascal;','');
AssertProc([],ccPascal,0);
end;
Procedure TTestProcedureFunction.TestFunctionPascal;
procedure TTestProcedureFunction.TestFunctionPascal;
begin
ParseFunction('','','',ccPascal);
AssertFunc([],ccPascal,0);
end;
Procedure TTestProcedureFunction.TestProcedureStdCall;
procedure TTestProcedureFunction.TestProcedureStdCall;
begin
ParseProcedure('; stdcall;','');
AssertProc([],ccstdcall,0);
end;
Procedure TTestProcedureFunction.TestFunctionStdCall;
procedure TTestProcedureFunction.TestFunctionStdCall;
begin
ParseFunction('','','',ccStdCall);
AssertFunc([],ccStdCall,0);
end;
Procedure TTestProcedureFunction.TestProcedureOldFPCCall;
procedure TTestProcedureFunction.TestProcedureOldFPCCall;
begin
ParseProcedure('; oldfpccall;','');
AssertProc([],ccoldfpccall,0);
end;
Procedure TTestProcedureFunction.TestFunctionOldFPCCall;
procedure TTestProcedureFunction.TestFunctionOldFPCCall;
begin
ParseFunction('','','',ccOldFPCCall);
AssertFunc([],ccOldFPCCall,0);
end;
Procedure TTestProcedureFunction.TestProcedurePublic;
procedure TTestProcedureFunction.TestProcedurePublic;
begin
ParseProcedure('; public name ''myfunc'';','');
AssertProc([pmPublic],ccDefault,0);
AssertExpression('Public name',Proc.PublicName,pekString,'''myfunc''');
end;
Procedure TTestProcedureFunction.TestProcedurePublicIdent;
procedure TTestProcedureFunction.TestProcedurePublicIdent;
begin
ParseProcedure('; public name exportname;','');
AssertProc([pmPublic],ccDefault,0);
AssertExpression('Public name',Proc.PublicName,pekIdent,'exportname');
end;
Procedure TTestProcedureFunction.TestFunctionPublic;
procedure TTestProcedureFunction.TestFunctionPublic;
begin
AddDeclaration('function A : Integer; public name exportname');
ParseFunction;
@ -830,14 +846,14 @@ begin
AssertExpression('Public name',Func.PublicName,pekIdent,'exportname');
end;
Procedure TTestProcedureFunction.TestProcedureCdeclPublic;
procedure TTestProcedureFunction.TestProcedureCdeclPublic;
begin
ParseProcedure('; cdecl; public name exportname;','');
AssertProc([pmPublic],ccCDecl,0);
AssertExpression('Public name',Proc.PublicName,pekIdent,'exportname');
end;
Procedure TTestProcedureFunction.TestFunctionCdeclPublic;
procedure TTestProcedureFunction.TestFunctionCdeclPublic;
begin
AddDeclaration('function A : Integer; cdecl; public name exportname');
ParseFunction;
@ -845,58 +861,58 @@ begin
AssertExpression('Public name',Func.PublicName,pekIdent,'exportname');
end;
Procedure TTestProcedureFunction.TestProcedureOverload;
procedure TTestProcedureFunction.TestProcedureOverload;
begin
ParseProcedure('; overload;','');
AssertProc([pmOverload],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestFunctionOverload;
procedure TTestProcedureFunction.TestFunctionOverload;
begin
AddDeclaration('function A : Integer; overload');
ParseFunction;
AssertFunc([pmOverload],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestProcedureVarargs;
procedure TTestProcedureFunction.TestProcedureVarargs;
begin
ParseProcedure('; varargs;','');
AssertProc([pmVarArgs],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestFunctionVarArgs;
procedure TTestProcedureFunction.TestFunctionVarArgs;
begin
AddDeclaration('function A : Integer; varargs');
ParseFunction;
AssertFunc([pmVarArgs],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestProcedureCDeclVarargs;
procedure TTestProcedureFunction.TestProcedureCDeclVarargs;
begin
ParseProcedure(';cdecl; varargs;','');
AssertProc([pmVarArgs],ccCDecl,0);
end;
Procedure TTestProcedureFunction.TestFunctionCDeclVarArgs;
procedure TTestProcedureFunction.TestFunctionCDeclVarArgs;
begin
AddDeclaration('function A : Integer; cdecl; varargs');
ParseFunction;
AssertFunc([pmVarArgs],ccCdecl,0);
end;
Procedure TTestProcedureFunction.TestProcedureForwardInterface;
procedure TTestProcedureFunction.TestProcedureForwardInterface;
begin
AddDeclaration('procedure A; forward;');
AssertException(EParserError,@ParseProcedure);
end;
Procedure TTestProcedureFunction.TestFunctionForwardInterface;
procedure TTestProcedureFunction.TestFunctionForwardInterface;
begin
AddDeclaration('function A : integer; forward;');
AssertException(EParserError,@ParseFunction);
end;
Procedure TTestProcedureFunction.TestProcedureForward;
procedure TTestProcedureFunction.TestProcedureForward;
begin
UseImplementation:=True;
AddDeclaration('procedure A; forward;');
@ -904,7 +920,7 @@ begin
AssertProc([pmforward],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestFunctionForward;
procedure TTestProcedureFunction.TestFunctionForward;
begin
UseImplementation:=True;
AddDeclaration('function A : integer; forward;');
@ -912,7 +928,7 @@ begin
AssertFunc([pmforward],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestProcedureCdeclForward;
procedure TTestProcedureFunction.TestProcedureCdeclForward;
begin
UseImplementation:=True;
AddDeclaration('procedure A; cdecl; forward;');
@ -920,7 +936,7 @@ begin
AssertProc([pmforward],ccCDecl,0);
end;
Procedure TTestProcedureFunction.TestFunctionCDeclForward;
procedure TTestProcedureFunction.TestFunctionCDeclForward;
begin
UseImplementation:=True;
AddDeclaration('function A : integer; cdecl; forward;');
@ -928,92 +944,92 @@ begin
AssertFunc([pmforward],ccCDecl,0);
end;
Procedure TTestProcedureFunction.TestProcedureCompilerProc;
procedure TTestProcedureFunction.TestProcedureCompilerProc;
begin
ParseProcedure(';compilerproc;','');
AssertProc([pmCompilerProc],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestFunctionCompilerProc;
procedure TTestProcedureFunction.TestFunctionCompilerProc;
begin
AddDeclaration('function A : Integer; compilerproc');
ParseFunction;
AssertFunc([pmCompilerProc],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestProcedureCDeclCompilerProc;
procedure TTestProcedureFunction.TestProcedureCDeclCompilerProc;
begin
ParseProcedure(';cdecl;compilerproc;','');
AssertProc([pmCompilerProc],ccCDecl,0);
end;
Procedure TTestProcedureFunction.TestFunctionCDeclCompilerProc;
procedure TTestProcedureFunction.TestFunctionCDeclCompilerProc;
begin
AddDeclaration('function A : Integer; cdecl; compilerproc');
ParseFunction;
AssertFunc([pmCompilerProc],ccCDecl,0);
end;
Procedure TTestProcedureFunction.TestProcedureAssembler;
procedure TTestProcedureFunction.TestProcedureAssembler;
begin
ParseProcedure(';assembler;','');
AssertProc([pmAssembler],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestFunctionAssembler;
procedure TTestProcedureFunction.TestFunctionAssembler;
begin
AddDeclaration('function A : Integer; assembler');
ParseFunction;
AssertFunc([pmAssembler],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestProcedureCDeclAssembler;
procedure TTestProcedureFunction.TestProcedureCDeclAssembler;
begin
ParseProcedure(';cdecl;assembler;','');
AssertProc([pmAssembler],ccCDecl,0);
end;
Procedure TTestProcedureFunction.TestFunctionCDeclAssembler;
procedure TTestProcedureFunction.TestFunctionCDeclAssembler;
begin
AddDeclaration('function A : Integer; cdecl; assembler');
ParseFunction;
AssertFunc([pmAssembler],ccCDecl,0);
end;
Procedure TTestProcedureFunction.TestProcedureExport;
procedure TTestProcedureFunction.TestProcedureExport;
begin
ParseProcedure(';export;','');
AssertProc([pmExport],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestFunctionExport;
procedure TTestProcedureFunction.TestFunctionExport;
begin
AddDeclaration('function A : Integer; export');
ParseFunction;
AssertFunc([pmExport],ccDefault,0);
end;
Procedure TTestProcedureFunction.TestProcedureCDeclExport;
procedure TTestProcedureFunction.TestProcedureCDeclExport;
begin
ParseProcedure('cdecl;export;','');
AssertProc([pmExport],ccCDecl,0);
end;
Procedure TTestProcedureFunction.TestFunctionCDeclExport;
procedure TTestProcedureFunction.TestFunctionCDeclExport;
begin
AddDeclaration('function A : Integer; cdecl; export');
ParseFunction;
AssertFunc([pmExport],ccCDecl,0);
end;
Procedure TTestProcedureFunction.TestProcedureExternal;
procedure TTestProcedureFunction.TestProcedureExternal;
begin
ParseProcedure(';external','');
AssertProc([pmExternal],ccDefault,0);
AssertNull('No Library name expression',Proc.LibraryExpr);
end;
Procedure TTestProcedureFunction.TestFunctionExternal;
procedure TTestProcedureFunction.TestFunctionExternal;
begin
AddDeclaration('function A : Integer; external');
ParseFunction;
@ -1021,14 +1037,14 @@ begin
AssertNull('No Library name expression',Func.LibraryExpr);
end;
Procedure TTestProcedureFunction.TestProcedureExternalLibName;
procedure TTestProcedureFunction.TestProcedureExternalLibName;
begin
ParseProcedure(';external ''libname''','');
AssertProc([pmExternal],ccDefault,0);
AssertExpression('Library name expression',Proc.LibraryExpr,pekString,'''libname''');
end;
Procedure TTestProcedureFunction.TestFunctionExternalLibName;
procedure TTestProcedureFunction.TestFunctionExternalLibName;
begin
AddDeclaration('function A : Integer; external ''libname''');
ParseFunction;
@ -1036,7 +1052,7 @@ begin
AssertExpression('Library name expression',Func.LibraryExpr,pekString,'''libname''');
end;
Procedure TTestProcedureFunction.TestProcedureExternalLibNameName;
procedure TTestProcedureFunction.TestProcedureExternalLibNameName;
begin
ParseProcedure(';external ''libname'' name ''symbolname''','');
AssertProc([pmExternal],ccDefault,0);
@ -1044,7 +1060,7 @@ begin
AssertExpression('Library symbol expression',Proc.LibrarySymbolName,pekString,'''symbolname''');
end;
Procedure TTestProcedureFunction.TestFunctionExternalLibNameName;
procedure TTestProcedureFunction.TestFunctionExternalLibNameName;
begin
AddDeclaration('function A : Integer; external ''libname'' name ''symbolname''');
ParseFunction;
@ -1053,7 +1069,7 @@ begin
AssertExpression('Library symbol expression',Func.LibrarySymbolName,pekString,'''symbolname''');
end;
Procedure TTestProcedureFunction.TestProcedureExternalName;
procedure TTestProcedureFunction.TestProcedureExternalName;
begin
ParseProcedure(';external name ''symbolname''','');
AssertProc([pmExternal],ccDefault,0);
@ -1061,7 +1077,7 @@ begin
AssertExpression('Library symbol expression',Proc.LibrarySymbolName,pekString,'''symbolname''');
end;
Procedure TTestProcedureFunction.TestFunctionExternalName;
procedure TTestProcedureFunction.TestFunctionExternalName;
begin
AddDeclaration('function A : Integer; external name ''symbolname''');
ParseFunction;
@ -1070,14 +1086,14 @@ begin
AssertExpression('Library symbol expression',Func.LibrarySymbolName,pekString,'''symbolname''');
end;
Procedure TTestProcedureFunction.TestProcedureCdeclExternal;
procedure TTestProcedureFunction.TestProcedureCdeclExternal;
begin
ParseProcedure('; cdecl; external','');
AssertProc([pmExternal],ccCdecl,0);
AssertNull('No Library name expression',Proc.LibraryExpr);
end;
Procedure TTestProcedureFunction.TestFunctionCdeclExternal;
procedure TTestProcedureFunction.TestFunctionCdeclExternal;
begin
AddDeclaration('function A : Integer; cdecl; external');
ParseFunction;
@ -1085,14 +1101,14 @@ begin
AssertNull('No Library name expression',Func.LibraryExpr);
end;
Procedure TTestProcedureFunction.TestProcedureCdeclExternalLibName;
procedure TTestProcedureFunction.TestProcedureCdeclExternalLibName;
begin
ParseProcedure('; cdecl; external ''libname''','');
AssertProc([pmExternal],ccCdecl,0);
AssertExpression('Library name expression',Proc.LibraryExpr,pekString,'''libname''');
end;
Procedure TTestProcedureFunction.TestFunctionCdeclExternalLibName;
procedure TTestProcedureFunction.TestFunctionCdeclExternalLibName;
begin
AddDeclaration('function A : Integer; cdecl; external ''libname''');
ParseFunction;
@ -1100,7 +1116,7 @@ begin
AssertExpression('Library name expression',Func.LibraryExpr,pekString,'''libname''');
end;
Procedure TTestProcedureFunction.TestProcedureCdeclExternalLibNameName;
procedure TTestProcedureFunction.TestProcedureCdeclExternalLibNameName;
begin
ParseProcedure('; cdecl; external ''libname'' name ''symbolname''','');
AssertProc([pmExternal],ccCdecl,0);
@ -1108,7 +1124,7 @@ begin
AssertExpression('Library symbol expression',Proc.LibrarySymbolName,pekString,'''symbolname''');
end;
Procedure TTestProcedureFunction.TestFunctionCdeclExternalLibNameName;
procedure TTestProcedureFunction.TestFunctionCdeclExternalLibNameName;
begin
AddDeclaration('function A : Integer; cdecl; external ''libname'' name ''symbolname''');
ParseFunction;
@ -1117,7 +1133,7 @@ begin
AssertExpression('Library symbol expression',Func.LibrarySymbolName,pekString,'''symbolname''');
end;
Procedure TTestProcedureFunction.TestProcedureCdeclExternalName;
procedure TTestProcedureFunction.TestProcedureCdeclExternalName;
begin
ParseProcedure('; cdecl; external name ''symbolname''','');
AssertProc([pmExternal],ccCdecl,0);
@ -1125,7 +1141,7 @@ begin
AssertExpression('Library symbol expression',Proc.LibrarySymbolName,pekString,'''symbolname''');
end;
Procedure TTestProcedureFunction.TestFunctionCdeclExternalName;
procedure TTestProcedureFunction.TestFunctionCdeclExternalName;
begin
AddDeclaration('function A : Integer; cdecl; external name ''symbolname''');
ParseFunction;
@ -1134,6 +1150,54 @@ begin
AssertExpression('Library symbol expression',Func.LibrarySymbolName,pekString,'''symbolname''');
end;
procedure TTestProcedureFunction.TestOperatorTokens;
Var
t : TOperatorType;
begin
For t:=otMul to High(TOperatorType) do
// No way to distinguish between logical/bitwise or/and/Xor
if not (t in [otBitwiseOr,otBitwiseAnd,otBitwiseXor]) then
begin
ResetParser;
if t in UnaryOperators then
AddDeclaration(Format('operator %s (a: Integer) : te',[OperatorTokens[t]]))
else
AddDeclaration(Format('operator %s (a: Integer; b: integer) : te',[OperatorTokens[t]]));
ParseOperator;
AssertEquals('Token based',Not (T in [otInc,otDec]),FOperator.TokenBased);
AssertEquals('Correct operator type',T,FOperator.OperatorType);
if t in UnaryOperators then
AssertEquals('Correct operator name',format('%s(Integer):te',[OperatorNames[t]]),FOperator.Name)
else
AssertEquals('Correct operator name',format('%s(Integer,Integer):te',[OperatorNames[t]]),FOperator.Name);
end;
end;
procedure TTestProcedureFunction.TestOperatorNames;
Var
t : TOperatorType;
begin
For t:=Succ(otUnknown) to High(TOperatorType) do
begin
ResetParser;
if t in UnaryOperators then
AddDeclaration(Format('operator %s (a: Integer) : te',[OperatorNames[t]]))
else
AddDeclaration(Format('operator %s (a: Integer; b: integer) : te',[OperatorNames[t]]));
ParseOperator;
AssertEquals('Token based',False,FOperator.TokenBased);
AssertEquals('Correct operator type',T,FOperator.OperatorType);
if t in UnaryOperators then
AssertEquals('Correct operator name',format('%s(Integer):te',[OperatorNames[t]]),FOperator.Name)
else
AssertEquals('Correct operator name',format('%s(Integer,Integer):te',[OperatorNames[t]]),FOperator.Name);
end;
end;
procedure TTestProcedureFunction.SetUp;
begin
Inherited;
@ -1144,7 +1208,7 @@ begin
Inherited;
end;
Procedure TTestProcedureFunction.AssertComment;
procedure TTestProcedureFunction.AssertComment;
begin
AssertEquals('Correct comment',' A comment'+sLineBreak,FProc.DocComment);
end;

View File

@ -169,7 +169,8 @@ type
procedure AssertVariantSelector(AName, AType: string);
procedure AssertField1(Hints: TPasMemberHints);
procedure AssertField2(Hints: TPasMemberHints);
procedure AssertMethod2(Hints: TPasMemberHints);
procedure AssertMethod2(Hints: TPasMemberHints; isClass : Boolean = False);
procedure AssertOperatorMethod2(Hints: TPasMemberHints; isClass : Boolean = False);
procedure AssertVariant1(Hints: TPasMemberHints);
procedure AssertVariant1(Hints: TPasMemberHints; VariantLabels : Array of string);
procedure AssertVariant2(Hints: TPasMemberHints);
@ -245,6 +246,7 @@ type
Procedure TestFieldAnd2Methods;
Procedure TestFieldAndProperty;
Procedure TestFieldAndClassMethod;
Procedure TestFieldAndClassOperator;
Procedure TestNested;
Procedure TestNestedDeprecated;
Procedure TestNestedPlatform;
@ -731,15 +733,20 @@ end;
Function TTestProcedureTypeParser.ParseType(ASource: String;
CC: TCallingConvention; ATypeClass: TClass; Const AHint: String
): TPasProcedureType;
Var
CCS : String;
begin
if CC=ccdefault then
Result:=TPasProcedureType(ParseType(ASource,ATypeClass,AHint))
else
begin
CCS:=cCallingConventions[CC];
if (AHint<>'') then
Result:=TPasProcedureType(ParseType(ASource+';' +cCallingConventions[CC]+';',ATypeClass,AHint))
Result:=TPasProcedureType(ParseType(ASource+';' +CCS+';',ATypeClass,AHint))
else
Result:=TPasProcedureType(ParseType(ASource+';' +cCallingConventions[CC],ATypeClass,AHint));
Result:=TPasProcedureType(ParseType(ASource+';' +CCS,ATypeClass,AHint));
end;
FProc:=Result;
AssertEquals('Correct calling convention for procedural type',cc,Result.CallingConvention);
@ -1468,18 +1475,37 @@ begin
AssertTrue('Field 2 hints match',Field2.Hints=Hints)
end;
procedure TTestRecordTypeParser.AssertMethod2(Hints: TPasMemberHints);
procedure TTestRecordTypeParser.AssertMethod2(Hints: TPasMemberHints; isClass : Boolean = False);
Var
P : TPasProcedure;
begin
AssertEquals('Member 2 type',TPasProcedure,TObject(TheRecord.Members[1]).ClassType);
if IsClass then
AssertEquals('Member 2 type',TPasClassProcedure,TObject(TheRecord.Members[1]).ClassType)
else
AssertEquals('Member 2 type',TPasProcedure,TObject(TheRecord.Members[1]).ClassType);
P:=TPasProcedure(TheRecord.Members[1]);
AssertEquals('Method name','dosomething2',P.Name);
AssertTrue('Method hints match',P.Hints=Hints)
end;
procedure TTestRecordTypeParser.AssertOperatorMethod2(Hints: TPasMemberHints;
isClass: Boolean);
Var
P : TPasOperator;
begin
if IsClass then
AssertEquals('Member 2 type',TPasClassOperator,TObject(TheRecord.Members[1]).ClassType)
else
AssertEquals('Member 2 type',TPasOperator,TObject(TheRecord.Members[1]).ClassType);
P:=TPasOperator(TheRecord.Members[1]);
AssertEquals('Method name','assign(ta,Cardinal):Boolean',P.Name);
AssertTrue('Method hints match',P.Hints=Hints)
end;
procedure TTestRecordTypeParser.AssertOneIntegerField(Hints : TPasMemberHints);
begin
@ -1883,11 +1909,30 @@ Var
P : TPasFunction;
begin
Parser.Options:=[po_delphi];
TestFields(['x : integer;','class procedure dosomething2;','function dosomething3 : Integer;'],'',False);
AssertEquals('Member count',3,TheRecord.Members.Count);
AssertField1([]);
AssertMethod2([]);
AssertEquals('Class procedure',TPasProcedure,TObject(TheRecord.Members[1]).ClassType);
AssertMethod2([],True);
AssertEquals('Class procedure',TPasClassProcedure,TObject(TheRecord.Members[1]).ClassType);
AssertEquals('Member 3 type',TPasFunction,TObject(TheRecord.Members[2]).ClassType);
P:=TPasFunction(TheRecord.Members[2]);
AssertEquals('Method 2 name','dosomething3',P.Name);
AssertTrue('Method 2 hints match',[]=P.Hints);
// Standard type
AssertEquals('Method 2 result type','Integer', P.FuncType.ResultEl.ResultType.Name);
end;
procedure TTestRecordTypeParser.TestFieldAndClassOperator;
Var
P : TPasFunction;
begin
TestFields(['x : integer;','class operator assign(a : ta; b : Cardinal) : boolean;','function dosomething3 : Integer;'],'',False);
AssertEquals('Member count',3,TheRecord.Members.Count);
AssertField1([]);
AssertOperatorMethod2([],True);
AssertEquals('Member 3 type',TPasFunction,TObject(TheRecord.Members[2]).ClassType);
P:=TPasFunction(TheRecord.Members[2]);
AssertEquals('Method 2 name','dosomething3',P.Name);

View File

@ -30,7 +30,7 @@
<RunParams>
<local>
<FormatVersion Value="1"/>
<CommandLineParams Value="--suite=TTestStatementParser.TestAsm"/>
<CommandLineParams Value="--suite=TTestProcedureFunction.TestOperatorTokens"/>
</local>
</RunParams>
<RequiredPackages Count="1">
@ -46,22 +46,18 @@
<Unit1>
<Filename Value="tcscanner.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="tcscanner"/>
</Unit1>
<Unit2>
<Filename Value="tctypeparser.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="tctypeparser"/>
</Unit2>
<Unit3>
<Filename Value="tcstatements.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="tcstatements"/>
</Unit3>
<Unit4>
<Filename Value="tcbaseparser.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="tcbaseparser"/>
</Unit4>
<Unit5>
<Filename Value="tcmoduleparser.pas"/>
@ -74,7 +70,6 @@
<Unit7>
<Filename Value="tcvarparser.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="tcvarparser"/>
</Unit7>
<Unit8>
<Filename Value="tcclasstype.pas"/>
@ -83,7 +78,6 @@
<Unit9>
<Filename Value="tcexprparser.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="tcexprparser"/>
</Unit9>
<Unit10>
<Filename Value="tcprocfunc.pas"/>