|
@@ -246,6 +246,9 @@ Works:
|
|
- visibility
|
|
- visibility
|
|
- property
|
|
- property
|
|
- helper method, Self as var argument
|
|
- helper method, Self as var argument
|
|
|
|
+- generics
|
|
|
|
+- array of const
|
|
|
|
+- attributes
|
|
|
|
|
|
ToDo:
|
|
ToDo:
|
|
- operator overload
|
|
- operator overload
|
|
@@ -263,10 +266,6 @@ ToDo:
|
|
- CharSet:=[#13]
|
|
- CharSet:=[#13]
|
|
- proc: check if forward and impl default values match
|
|
- proc: check if forward and impl default values match
|
|
- call array of proc without ()
|
|
- call array of proc without ()
|
|
-- attributes
|
|
|
|
-- type helpers
|
|
|
|
-- record/class helpers
|
|
|
|
-- array of const
|
|
|
|
- generics, nested param lists
|
|
- generics, nested param lists
|
|
- object
|
|
- object
|
|
- futures
|
|
- futures
|
|
@@ -1352,7 +1351,8 @@ type
|
|
rcNoImplicitProc, // do not call a function without params, includes rcNoImplicitProcType
|
|
rcNoImplicitProc, // do not call a function without params, includes rcNoImplicitProcType
|
|
rcNoImplicitProcType, // do not call a proc type without params
|
|
rcNoImplicitProcType, // do not call a proc type without params
|
|
rcConstant, // resolve a constant expression, error if not computable
|
|
rcConstant, // resolve a constant expression, error if not computable
|
|
- rcType // resolve a type expression
|
|
|
|
|
|
+ rcType, // resolve a type expression
|
|
|
|
+ rcCall // resolve result type of a function call
|
|
);
|
|
);
|
|
TPasResolverComputeFlags = set of TPasResolverComputeFlag;
|
|
TPasResolverComputeFlags = set of TPasResolverComputeFlag;
|
|
|
|
|
|
@@ -1760,7 +1760,9 @@ type
|
|
function FindUsedUnit(const aName: string; aMod: TPasModule): TPasModule;
|
|
function FindUsedUnit(const aName: string; aMod: TPasModule): TPasModule;
|
|
procedure FinishAssertCall(Proc: TResElDataBuiltInProc;
|
|
procedure FinishAssertCall(Proc: TResElDataBuiltInProc;
|
|
Params: TParamsExpr); virtual;
|
|
Params: TParamsExpr); virtual;
|
|
- function FindClassTypeAndConstructor(const aUnitName, aClassName: string;
|
|
|
|
|
|
+ function FindSystemClassType(const aUnitName, aClassName: string;
|
|
|
|
+ ErrorEl: TPasElement): TPasClassType; virtual;
|
|
|
|
+ function FindSystemClassTypeAndConstructor(const aUnitName, aClassName: string;
|
|
out aClass: TPasClassType; out aConstructor: TPasConstructor;
|
|
out aClass: TPasClassType; out aConstructor: TPasConstructor;
|
|
ErrorEl: TPasElement): boolean; virtual;
|
|
ErrorEl: TPasElement): boolean; virtual;
|
|
procedure FindAssertExceptionConstructors(ErrorEl: TPasElement); virtual;
|
|
procedure FindAssertExceptionConstructors(ErrorEl: TPasElement); virtual;
|
|
@@ -2187,6 +2189,8 @@ type
|
|
// find value and type of an element
|
|
// find value and type of an element
|
|
procedure ComputeElement(El: TPasElement; out ResolvedEl: TPasResolverResult;
|
|
procedure ComputeElement(El: TPasElement; out ResolvedEl: TPasResolverResult;
|
|
Flags: TPasResolverComputeFlags; StartEl: TPasElement = nil);
|
|
Flags: TPasResolverComputeFlags; StartEl: TPasElement = nil);
|
|
|
|
+ procedure ComputeResultElement(El: TPasResultElement; out ResolvedEl: TPasResolverResult;
|
|
|
|
+ Flags: TPasResolverComputeFlags; StartEl: TPasElement = nil); virtual;
|
|
function Eval(Expr: TPasExpr; Flags: TResEvalFlags; Store: boolean = true): TResEvalValue; overload;
|
|
function Eval(Expr: TPasExpr; Flags: TResEvalFlags; Store: boolean = true): TResEvalValue; overload;
|
|
function Eval(const Value: TPasResolverResult; Flags: TResEvalFlags; Store: boolean = true): TResEvalValue; overload;
|
|
function Eval(const Value: TPasResolverResult; Flags: TResEvalFlags; Store: boolean = true): TResEvalValue; overload;
|
|
// checking compatibilility
|
|
// checking compatibilility
|
|
@@ -2293,6 +2297,7 @@ type
|
|
function GetInlineSpecOfNameExpr(El: TPasExpr): TInlineSpecializeExpr;
|
|
function GetInlineSpecOfNameExpr(El: TPasExpr): TInlineSpecializeExpr;
|
|
function GetUsesUnitInFilename(InFileExpr: TPasExpr): string;
|
|
function GetUsesUnitInFilename(InFileExpr: TPasExpr): string;
|
|
function GetPathStart(El: TPasExpr): TPasExpr;
|
|
function GetPathStart(El: TPasExpr): TPasExpr;
|
|
|
|
+ function GetPathEndIdent(El: TPasExpr; AllowCall: boolean): TPasExpr;
|
|
function GetNewInstanceExpr(El: TPasExpr): TPasExpr;
|
|
function GetNewInstanceExpr(El: TPasExpr): TPasExpr;
|
|
function ParentNeedsExprResult(El: TPasExpr): boolean;
|
|
function ParentNeedsExprResult(El: TPasExpr): boolean;
|
|
function GetReference_ConstructorType(Ref: TResolvedReference; Expr: TPasExpr): TPasResolverResult;
|
|
function GetReference_ConstructorType(Ref: TResolvedReference; Expr: TPasExpr): TPasResolverResult;
|
|
@@ -4703,6 +4708,29 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TPasResolver.GetPathEndIdent(El: TPasExpr; AllowCall: boolean
|
|
|
|
+ ): TPasExpr;
|
|
|
|
+// a -> a
|
|
|
|
+// a.b -> b
|
|
|
|
+// a.b() -> b
|
|
|
|
+// a()() -> nil
|
|
|
|
+// a[] -> nil
|
|
|
|
+var
|
|
|
|
+ Bin: TBinaryExpr;
|
|
|
|
+begin
|
|
|
|
+ Result:=nil;
|
|
|
|
+ if AllowCall and (El is TParamsExpr) then
|
|
|
|
+ El:=TParamsExpr(El).Value;
|
|
|
|
+ while El is TBinaryExpr do
|
|
|
|
+ begin
|
|
|
|
+ Bin:=TBinaryExpr(El);
|
|
|
|
+ if Bin.OpCode=eopSubIdent then
|
|
|
|
+ El:=Bin.right;
|
|
|
|
+ end;
|
|
|
|
+ if (El is TPrimitiveExpr) and (TPrimitiveExpr(El).Kind=pekIdent) then
|
|
|
|
+ Result:=El;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TPasResolver.GetNewInstanceExpr(El: TPasExpr): TPasExpr;
|
|
function TPasResolver.GetNewInstanceExpr(El: TPasExpr): TPasExpr;
|
|
// if the expression is a constructor newinstance call,
|
|
// if the expression is a constructor newinstance call,
|
|
// return the element referring the constructor
|
|
// return the element referring the constructor
|
|
@@ -5636,7 +5664,7 @@ begin
|
|
if bsRangeChecks in CurrentParser.Scanner.CurrentBoolSwitches then
|
|
if bsRangeChecks in CurrentParser.Scanner.CurrentBoolSwitches then
|
|
begin
|
|
begin
|
|
Include(ModScope.Flags,pmsfRangeErrorNeeded);
|
|
Include(ModScope.Flags,pmsfRangeErrorNeeded);
|
|
- FindRangeErrorConstructors(CurModule);
|
|
|
|
|
|
+ FindRangeErrorConstructors(nil);
|
|
end;
|
|
end;
|
|
|
|
|
|
if (CurModuleClass=TPasProgram) then
|
|
if (CurModuleClass=TPasProgram) then
|
|
@@ -6732,6 +6760,7 @@ var
|
|
Args, TemplTypes: TFPList;
|
|
Args, TemplTypes: TFPList;
|
|
Arg: TPasArgument;
|
|
Arg: TPasArgument;
|
|
ProcTypeScope: TPasProcTypeScope;
|
|
ProcTypeScope: TPasProcTypeScope;
|
|
|
|
+ C: TClass;
|
|
begin
|
|
begin
|
|
if TopScope.Element=El then
|
|
if TopScope.Element=El then
|
|
begin
|
|
begin
|
|
@@ -6815,6 +6844,19 @@ begin
|
|
sInvalidXModifierY,[GetElementTypeName(Proc),'external, '+ProcTypeModifiers[ptm]],Proc);
|
|
sInvalidXModifierY,[GetElementTypeName(Proc),'external, '+ProcTypeModifiers[ptm]],Proc);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ if El.IsAsync then
|
|
|
|
+ begin
|
|
|
|
+ // async procedure
|
|
|
|
+ C:=Proc.ClassType;
|
|
|
|
+ if (C<>TPasProcedure)
|
|
|
|
+ and (C<>TPasFunction)
|
|
|
|
+ and (C<>TPasClassProcedure)
|
|
|
|
+ and (C<>TPasClassFunction)
|
|
|
|
+ and (C<>TPasAnonymousProcedure)
|
|
|
|
+ and (C<>TPasAnonymousFunction) then
|
|
|
|
+ RaiseMsg(20200524105449,nInvalidXModifierY,sInvalidXModifierY,[GetElementTypeName(Proc),'async'],Proc);
|
|
|
|
+ end;
|
|
|
|
+
|
|
IsClassConDestructor:=(Proc.ClassType=TPasClassConstructor)
|
|
IsClassConDestructor:=(Proc.ClassType=TPasClassConstructor)
|
|
or (Proc.ClassType=TPasClassDestructor);
|
|
or (Proc.ClassType=TPasClassDestructor);
|
|
if IsClassConDestructor then
|
|
if IsClassConDestructor then
|
|
@@ -7976,6 +8018,8 @@ var
|
|
if not IsBaseType(ResultType,btBoolean,true) then
|
|
if not IsBaseType(ResultType,btBoolean,true) then
|
|
RaiseXExpectedButYFound(20170923200836,'function: boolean',
|
|
RaiseXExpectedButYFound(20170923200836,'function: boolean',
|
|
'function:'+GetTypeDescription(ResultType),PropEl.StoredAccessor);
|
|
'function:'+GetTypeDescription(ResultType),PropEl.StoredAccessor);
|
|
|
|
+ if Proc.IsAsync then
|
|
|
|
+ RaiseInvalidProcTypeModifier(20200524104719,Proc.ProcType,ptmAsync,Expr);
|
|
// check arg count
|
|
// check arg count
|
|
ExpArgCnt:=0;
|
|
ExpArgCnt:=0;
|
|
if IndexVal<>nil then
|
|
if IndexVal<>nil then
|
|
@@ -8041,7 +8085,7 @@ var
|
|
AncIndexResolved: TPasResolverResult;
|
|
AncIndexResolved: TPasResolverResult;
|
|
m: TVariableModifier;
|
|
m: TVariableModifier;
|
|
IndexVal: TResEvalValue;
|
|
IndexVal: TResEvalValue;
|
|
- AncIndexExpr: TPasExpr;
|
|
|
|
|
|
+ AncIndexExpr, ErrorEl: TPasExpr;
|
|
CurClass: TPasClassType;
|
|
CurClass: TPasClassType;
|
|
begin
|
|
begin
|
|
CheckTopScope(TPasPropertyScope);
|
|
CheckTopScope(TPasPropertyScope);
|
|
@@ -8135,19 +8179,20 @@ begin
|
|
if PropEl.ReadAccessor<>nil then
|
|
if PropEl.ReadAccessor<>nil then
|
|
begin
|
|
begin
|
|
// check compatibility
|
|
// check compatibility
|
|
|
|
+ ErrorEl:=PropEl.ReadAccessor;
|
|
AccEl:=ResolveAccessor(PropEl.ReadAccessor);
|
|
AccEl:=ResolveAccessor(PropEl.ReadAccessor);
|
|
if (AccEl.ClassType=TPasVariable) or (AccEl.ClassType=TPasConst) then
|
|
if (AccEl.ClassType=TPasVariable) or (AccEl.ClassType=TPasConst) then
|
|
begin
|
|
begin
|
|
if (PropEl.Args.Count>0) then
|
|
if (PropEl.Args.Count>0) then
|
|
- RaiseXExpectedButYFound(20170216151823,'function',GetElementTypeName(AccEl),PropEl.ReadAccessor);
|
|
|
|
|
|
+ RaiseXExpectedButYFound(20170216151823,'function',GetElementTypeName(AccEl),ErrorEl);
|
|
if not IsSameType(TPasVariable(AccEl).VarType,PropType,prraAlias) then
|
|
if not IsSameType(TPasVariable(AccEl).VarType,PropType,prraAlias) then
|
|
RaiseIncompatibleType(20170216151826,nIncompatibleTypesGotExpected,
|
|
RaiseIncompatibleType(20170216151826,nIncompatibleTypesGotExpected,
|
|
- [],PropType,TPasVariable(AccEl).VarType,PropEl.ReadAccessor);
|
|
|
|
|
|
+ [],PropType,TPasVariable(AccEl).VarType,ErrorEl);
|
|
if (vmClass in PropEl.VarModifiers)<>(vmClass in TPasVariable(AccEl).VarModifiers) then
|
|
if (vmClass in PropEl.VarModifiers)<>(vmClass in TPasVariable(AccEl).VarModifiers) then
|
|
if vmClass in PropEl.VarModifiers then
|
|
if vmClass in PropEl.VarModifiers then
|
|
- RaiseXExpectedButYFound(20170216151828,'class var','var',PropEl.ReadAccessor)
|
|
|
|
|
|
+ RaiseXExpectedButYFound(20170216151828,'class var','var',ErrorEl)
|
|
else
|
|
else
|
|
- RaiseXExpectedButYFound(20170216151831,'var','class var',PropEl.ReadAccessor);
|
|
|
|
|
|
+ RaiseXExpectedButYFound(20170216151831,'var','class var',ErrorEl);
|
|
end
|
|
end
|
|
else if AccEl is TPasProcedure then
|
|
else if AccEl is TPasProcedure then
|
|
begin
|
|
begin
|
|
@@ -8156,23 +8201,26 @@ begin
|
|
if (vmClass in PropEl.VarModifiers) then
|
|
if (vmClass in PropEl.VarModifiers) then
|
|
begin
|
|
begin
|
|
if Proc.ClassType<>TPasClassFunction then
|
|
if Proc.ClassType<>TPasClassFunction then
|
|
- RaiseXExpectedButYFound(20170216151834,'class function',GetElementTypeName(Proc),PropEl.ReadAccessor);
|
|
|
|
|
|
+ RaiseXExpectedButYFound(20170216151834,'class function',GetElementTypeName(Proc),ErrorEl);
|
|
if not CheckClassAccessorStatic(Proc.IsStatic) then
|
|
if not CheckClassAccessorStatic(Proc.IsStatic) then
|
|
if Proc.IsStatic then
|
|
if Proc.IsStatic then
|
|
- RaiseMsg(20170216151837,nClassPropertyAccessorMustNotBeStatic,sClassPropertyAccessorMustNotBeStatic,[],PropEl.ReadAccessor)
|
|
|
|
|
|
+ RaiseMsg(20170216151837,nClassPropertyAccessorMustNotBeStatic,sClassPropertyAccessorMustNotBeStatic,[],ErrorEl)
|
|
else
|
|
else
|
|
- RaiseMsg(20170216151839,nClassPropertyAccessorMustBeStatic,sClassPropertyAccessorMustBeStatic,[],PropEl.ReadAccessor);
|
|
|
|
|
|
+ RaiseMsg(20170216151839,nClassPropertyAccessorMustBeStatic,sClassPropertyAccessorMustBeStatic,[],ErrorEl);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
if Proc.ClassType<>TPasFunction then
|
|
if Proc.ClassType<>TPasFunction then
|
|
- RaiseXExpectedButYFound(20170216151842,'function',GetElementTypeName(Proc),PropEl.ReadAccessor);
|
|
|
|
|
|
+ RaiseXExpectedButYFound(20170216151842,'function',GetElementTypeName(Proc),ErrorEl);
|
|
end;
|
|
end;
|
|
// check function result type
|
|
// check function result type
|
|
ResultType:=TPasFunction(Proc).FuncType.ResultEl.ResultType;
|
|
ResultType:=TPasFunction(Proc).FuncType.ResultEl.ResultType;
|
|
if not IsSameType(ResultType,PropType,prraAlias) then
|
|
if not IsSameType(ResultType,PropType,prraAlias) then
|
|
RaiseXExpectedButYFound(20170216151844,'function result '+GetTypeDescription(PropType,true),
|
|
RaiseXExpectedButYFound(20170216151844,'function result '+GetTypeDescription(PropType,true),
|
|
- GetTypeDescription(ResultType,true),PropEl.ReadAccessor);
|
|
|
|
|
|
+ GetTypeDescription(ResultType,true),ErrorEl);
|
|
|
|
+ if Proc.IsAsync then
|
|
|
|
+ RaiseMsg(20200526101546,nInvalidXModifierY,sInvalidXModifierY,['property getter',
|
|
|
|
+ ProcTypeModifiers[ptmAsync]],ErrorEl);
|
|
// check args
|
|
// check args
|
|
CheckArgs(Proc,IndexVal,IndexResolved,PropEl.ReadAccessor);
|
|
CheckArgs(Proc,IndexVal,IndexResolved,PropEl.ReadAccessor);
|
|
NeedArgCnt:=PropEl.Args.Count;
|
|
NeedArgCnt:=PropEl.Args.Count;
|
|
@@ -8180,29 +8228,30 @@ begin
|
|
inc(NeedArgCnt);
|
|
inc(NeedArgCnt);
|
|
if Proc.ProcType.Args.Count<>NeedArgCnt then
|
|
if Proc.ProcType.Args.Count<>NeedArgCnt then
|
|
RaiseMsg(20170216151847,nWrongNumberOfParametersForCallTo,sWrongNumberOfParametersForCallTo,
|
|
RaiseMsg(20170216151847,nWrongNumberOfParametersForCallTo,sWrongNumberOfParametersForCallTo,
|
|
- [Proc.Name],PropEl.ReadAccessor);
|
|
|
|
|
|
+ [Proc.Name],ErrorEl);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
- RaiseXExpectedButYFound(20170216151850,'variable',GetElementTypeName(AccEl),PropEl.ReadAccessor);
|
|
|
|
|
|
+ RaiseXExpectedButYFound(20170216151850,'variable',GetElementTypeName(AccEl),ErrorEl);
|
|
end;
|
|
end;
|
|
|
|
|
|
if PropEl.WriteAccessor<>nil then
|
|
if PropEl.WriteAccessor<>nil then
|
|
begin
|
|
begin
|
|
// check compatibility
|
|
// check compatibility
|
|
|
|
+ ErrorEl:=PropEl.WriteAccessor;
|
|
AccEl:=ResolveAccessor(PropEl.WriteAccessor);
|
|
AccEl:=ResolveAccessor(PropEl.WriteAccessor);
|
|
if (AccEl.ClassType=TPasVariable)
|
|
if (AccEl.ClassType=TPasVariable)
|
|
or ((AccEl.ClassType=TPasConst) and (not TPasConst(AccEl).IsConst)) then
|
|
or ((AccEl.ClassType=TPasConst) and (not TPasConst(AccEl).IsConst)) then
|
|
begin
|
|
begin
|
|
if (PropEl.Args.Count>0) then
|
|
if (PropEl.Args.Count>0) then
|
|
- RaiseXExpectedButYFound(20170216151852,'procedure',GetElementTypeName(AccEl),PropEl.WriteAccessor);
|
|
|
|
|
|
+ RaiseXExpectedButYFound(20170216151852,'procedure',GetElementTypeName(AccEl),ErrorEl);
|
|
if not IsSameType(TPasVariable(AccEl).VarType,PropType,prraAlias) then
|
|
if not IsSameType(TPasVariable(AccEl).VarType,PropType,prraAlias) then
|
|
RaiseIncompatibleType(20170216151855,nIncompatibleTypesGotExpected,
|
|
RaiseIncompatibleType(20170216151855,nIncompatibleTypesGotExpected,
|
|
- [],PropType,TPasVariable(AccEl).VarType,PropEl.WriteAccessor);
|
|
|
|
|
|
+ [],PropType,TPasVariable(AccEl).VarType,ErrorEl);
|
|
if (vmClass in PropEl.VarModifiers)<>(vmClass in TPasVariable(AccEl).VarModifiers) then
|
|
if (vmClass in PropEl.VarModifiers)<>(vmClass in TPasVariable(AccEl).VarModifiers) then
|
|
if vmClass in PropEl.VarModifiers then
|
|
if vmClass in PropEl.VarModifiers then
|
|
- RaiseXExpectedButYFound(20170216151858,'class var','var',PropEl.WriteAccessor)
|
|
|
|
|
|
+ RaiseXExpectedButYFound(20170216151858,'class var','var',ErrorEl)
|
|
else
|
|
else
|
|
- RaiseXExpectedButYFound(20170216151900,'var','class var',PropEl.WriteAccessor);
|
|
|
|
|
|
+ RaiseXExpectedButYFound(20170216151900,'var','class var',ErrorEl);
|
|
end
|
|
end
|
|
else if AccEl is TPasProcedure then
|
|
else if AccEl is TPasProcedure then
|
|
begin
|
|
begin
|
|
@@ -8211,38 +8260,41 @@ begin
|
|
if (vmClass in PropEl.VarModifiers) then
|
|
if (vmClass in PropEl.VarModifiers) then
|
|
begin
|
|
begin
|
|
if Proc.ClassType<>TPasClassProcedure then
|
|
if Proc.ClassType<>TPasClassProcedure then
|
|
- RaiseXExpectedButYFound(20170216151903,'class procedure',GetElementTypeName(Proc),PropEl.WriteAccessor);
|
|
|
|
|
|
+ RaiseXExpectedButYFound(20170216151903,'class procedure',GetElementTypeName(Proc),ErrorEl);
|
|
if not CheckClassAccessorStatic(Proc.IsStatic) then
|
|
if not CheckClassAccessorStatic(Proc.IsStatic) then
|
|
if Proc.IsStatic then
|
|
if Proc.IsStatic then
|
|
- RaiseMsg(20170216151905,nClassPropertyAccessorMustNotBeStatic,sClassPropertyAccessorMustNotBeStatic,[],PropEl.WriteAccessor)
|
|
|
|
|
|
+ RaiseMsg(20170216151905,nClassPropertyAccessorMustNotBeStatic,sClassPropertyAccessorMustNotBeStatic,[],ErrorEl)
|
|
else
|
|
else
|
|
- RaiseMsg(20170216151906,nClassPropertyAccessorMustBeStatic,sClassPropertyAccessorMustBeStatic,[],PropEl.WriteAccessor);
|
|
|
|
|
|
+ RaiseMsg(20170216151906,nClassPropertyAccessorMustBeStatic,sClassPropertyAccessorMustBeStatic,[],ErrorEl);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
if Proc.ClassType<>TPasProcedure then
|
|
if Proc.ClassType<>TPasProcedure then
|
|
- RaiseXExpectedButYFound(20170216151910,'procedure',GetElementTypeName(Proc),PropEl.WriteAccessor);
|
|
|
|
|
|
+ RaiseXExpectedButYFound(20170216151910,'procedure',GetElementTypeName(Proc),ErrorEl);
|
|
end;
|
|
end;
|
|
|
|
+ if Proc.IsAsync then
|
|
|
|
+ RaiseMsg(20200526101635,nInvalidXModifierY,sInvalidXModifierY,['property setter',
|
|
|
|
+ ProcTypeModifiers[ptmAsync]],ErrorEl);
|
|
// check args
|
|
// check args
|
|
- CheckArgs(Proc,IndexVal,IndexResolved,PropEl.ReadAccessor);
|
|
|
|
|
|
+ CheckArgs(Proc,IndexVal,IndexResolved,PropEl.WriteAccessor);
|
|
// check write arg
|
|
// check write arg
|
|
PropArgCount:=PropEl.Args.Count;
|
|
PropArgCount:=PropEl.Args.Count;
|
|
if IndexVal<>nil then
|
|
if IndexVal<>nil then
|
|
inc(PropArgCount);
|
|
inc(PropArgCount);
|
|
if Proc.ProcType.Args.Count<>PropArgCount+1 then
|
|
if Proc.ProcType.Args.Count<>PropArgCount+1 then
|
|
RaiseMsg(20170216151913,nWrongNumberOfParametersForCallTo,sWrongNumberOfParametersForCallTo,
|
|
RaiseMsg(20170216151913,nWrongNumberOfParametersForCallTo,sWrongNumberOfParametersForCallTo,
|
|
- [Proc.Name],PropEl.WriteAccessor);
|
|
|
|
|
|
+ [Proc.Name],ErrorEl);
|
|
Arg:=TPasArgument(Proc.ProcType.Args[PropArgCount]);
|
|
Arg:=TPasArgument(Proc.ProcType.Args[PropArgCount]);
|
|
if not (Arg.Access in [argDefault,argConst]) then
|
|
if not (Arg.Access in [argDefault,argConst]) then
|
|
RaiseMsg(20170216151917,nIncompatibleTypeArgNo,sIncompatibleTypeArgNo,
|
|
RaiseMsg(20170216151917,nIncompatibleTypeArgNo,sIncompatibleTypeArgNo,
|
|
[IntToStr(PropArgCount+1),AccessDescriptions[Arg.Access],
|
|
[IntToStr(PropArgCount+1),AccessDescriptions[Arg.Access],
|
|
- AccessDescriptions[argConst]],PropEl.WriteAccessor);
|
|
|
|
|
|
+ AccessDescriptions[argConst]],ErrorEl);
|
|
if not IsSameType(Arg.ArgType,PropType,prraAlias) then
|
|
if not IsSameType(Arg.ArgType,PropType,prraAlias) then
|
|
RaiseIncompatibleType(20170216151919,nIncompatibleTypeArgNo,
|
|
RaiseIncompatibleType(20170216151919,nIncompatibleTypeArgNo,
|
|
- [IntToStr(PropArgCount+1)],Arg.ArgType,PropType,PropEl.WriteAccessor);
|
|
|
|
|
|
+ [IntToStr(PropArgCount+1)],Arg.ArgType,PropType,ErrorEl);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
- RaiseXExpectedButYFound(20170216151921,'variable',GetElementTypeName(AccEl),PropEl.WriteAccessor);
|
|
|
|
|
|
+ RaiseXExpectedButYFound(20170216151921,'variable',GetElementTypeName(AccEl),ErrorEl);
|
|
end
|
|
end
|
|
else if (PropEl.ReadAccessor=nil) and (PropEl.VarType<>nil) then
|
|
else if (PropEl.ReadAccessor=nil) and (PropEl.VarType<>nil) then
|
|
RaiseMsg(20180519173551,nPropertyMustHaveReadOrWrite,sPropertyMustHaveReadOrWrite,[],PropEl);
|
|
RaiseMsg(20180519173551,nPropertyMustHaveReadOrWrite,sPropertyMustHaveReadOrWrite,[],PropEl);
|
|
@@ -9281,6 +9333,9 @@ begin
|
|
if CheckElTypeCompatibility(ImplResult,DeclResult,prraSimple)>cGenericExact then
|
|
if CheckElTypeCompatibility(ImplResult,DeclResult,prraSimple)>cGenericExact then
|
|
RaiseIncompatibleType(20170216151734,nResultTypeMismatchExpectedButFound,
|
|
RaiseIncompatibleType(20170216151734,nResultTypeMismatchExpectedButFound,
|
|
[],DeclResult,ImplResult,ImplProc);
|
|
[],DeclResult,ImplResult,ImplProc);
|
|
|
|
+
|
|
|
|
+ if ImplProc.IsAsync<>DeclProc.IsAsync then
|
|
|
|
+ RaiseMsg(20200524111856,nXModifierMismatchY,sXModifierMismatchY,['procedure type','async'],ImplProc);
|
|
end;
|
|
end;
|
|
|
|
|
|
// calling convention
|
|
// calling convention
|
|
@@ -10709,6 +10764,7 @@ begin
|
|
begin
|
|
begin
|
|
BuiltInProc:=TResElDataBuiltInProc(FoundEl.CustomData);
|
|
BuiltInProc:=TResElDataBuiltInProc(FoundEl.CustomData);
|
|
BuiltInProc.GetCallCompatibility(BuiltInProc,Params,true);
|
|
BuiltInProc.GetCallCompatibility(BuiltInProc,Params,true);
|
|
|
|
+ RaiseNotYetImplemented(20200525124749,FoundEl,'missing exception, Found=['+BuiltInProc.Signature+']');
|
|
end
|
|
end
|
|
else if FoundEl.CustomData is TResElDataBaseType then
|
|
else if FoundEl.CustomData is TResElDataBaseType then
|
|
CheckTypeCast(TPasUnresolvedSymbolRef(FoundEl),Params,true)
|
|
CheckTypeCast(TPasUnresolvedSymbolRef(FoundEl),Params,true)
|
|
@@ -13712,8 +13768,8 @@ begin
|
|
RaiseConstantExprExp(20170216152637,Params);
|
|
RaiseConstantExprExp(20170216152637,Params);
|
|
if Proc.ProcType is TPasFunctionType then
|
|
if Proc.ProcType is TPasFunctionType then
|
|
// function call => return result
|
|
// function call => return result
|
|
- ComputeElement(TPasFunctionType(Proc.ProcType).ResultEl,ResolvedEl,
|
|
|
|
- Flags+[rcNoImplicitProc],StartEl)
|
|
|
|
|
|
+ ComputeResultElement(TPasFunctionType(Proc.ProcType).ResultEl,ResolvedEl,
|
|
|
|
+ Flags+[rcCall],StartEl)
|
|
else if (Proc.ClassType=TPasConstructor) then
|
|
else if (Proc.ClassType=TPasConstructor) then
|
|
begin
|
|
begin
|
|
// constructor -> return value of type class
|
|
// constructor -> return value of type class
|
|
@@ -13738,8 +13794,8 @@ begin
|
|
RaiseConstantExprExp(20170216152639,Params);
|
|
RaiseConstantExprExp(20170216152639,Params);
|
|
if ResolvedEl.LoTypeEl is TPasFunctionType then
|
|
if ResolvedEl.LoTypeEl is TPasFunctionType then
|
|
// function call => return result
|
|
// function call => return result
|
|
- ComputeElement(TPasFunctionType(ResolvedEl.LoTypeEl).ResultEl,
|
|
|
|
- ResolvedEl,Flags+[rcNoImplicitProc],StartEl)
|
|
|
|
|
|
+ ComputeResultElement(TPasFunctionType(ResolvedEl.LoTypeEl).ResultEl,
|
|
|
|
+ ResolvedEl,Flags+[rcCall],StartEl)
|
|
else
|
|
else
|
|
// procedure call, result is neither readable nor writable
|
|
// procedure call, result is neither readable nor writable
|
|
SetResolverTypeExpr(ResolvedEl,btProc,
|
|
SetResolverTypeExpr(ResolvedEl,btProc,
|
|
@@ -14626,7 +14682,7 @@ begin
|
|
if not (ptm in [ptmOfObject]) then
|
|
if not (ptm in [ptmOfObject]) then
|
|
RaiseContextXInvalidY(20171221193455,'function GetEnumerator','modifier '+ProcTypeModifiers[ptm],Loop.StartExpr);
|
|
RaiseContextXInvalidY(20171221193455,'function GetEnumerator','modifier '+ProcTypeModifiers[ptm],Loop.StartExpr);
|
|
// check result type
|
|
// check result type
|
|
- ComputeElement(GetterFunc.FuncType.ResultEl,ResultResolved,[rcType]);
|
|
|
|
|
|
+ ComputeResultElement(GetterFunc.FuncType.ResultEl,ResultResolved,[rcCall]);
|
|
if (ResultResolved.BaseType<>btContext) then
|
|
if (ResultResolved.BaseType<>btContext) then
|
|
RaiseContextXExpectedButYFound(20171221193749,'function GetEnumerator','result class',GetTypeDescription(ResultResolved),Loop.StartExpr);
|
|
RaiseContextXExpectedButYFound(20171221193749,'function GetEnumerator','result class',GetTypeDescription(ResultResolved),Loop.StartExpr);
|
|
LoTypeEl:=ResultResolved.LoTypeEl;
|
|
LoTypeEl:=ResultResolved.LoTypeEl;
|
|
@@ -14656,7 +14712,7 @@ begin
|
|
if not (ptm in [ptmOfObject]) then
|
|
if not (ptm in [ptmOfObject]) then
|
|
RaiseContextXInvalidY(20171221195732,'function MoveNext','modifier '+ProcTypeModifiers[ptm],Loop.StartExpr);
|
|
RaiseContextXInvalidY(20171221195732,'function MoveNext','modifier '+ProcTypeModifiers[ptm],Loop.StartExpr);
|
|
// check result type
|
|
// check result type
|
|
- ComputeElement(MoveNextFunc.FuncType.ResultEl,MoveNextResolved,[rcType]);
|
|
|
|
|
|
+ ComputeResultElement(MoveNextFunc.FuncType.ResultEl,MoveNextResolved,[rcCall]);
|
|
if not (MoveNextResolved.BaseType in btAllBooleans) then
|
|
if not (MoveNextResolved.BaseType in btAllBooleans) then
|
|
RaiseContextXExpectedButYFound(20171221200337,'function MoveNext','result boolean',GetTypeDescription(MoveNextResolved),Loop.StartExpr);
|
|
RaiseContextXExpectedButYFound(20171221200337,'function MoveNext','result boolean',GetTypeDescription(MoveNextResolved),Loop.StartExpr);
|
|
|
|
|
|
@@ -14780,7 +14836,7 @@ begin
|
|
aMod:=RootElement;
|
|
aMod:=RootElement;
|
|
ModScope:=aMod.CustomData as TPasModuleScope;
|
|
ModScope:=aMod.CustomData as TPasModuleScope;
|
|
if not (pmsfAssertSearched in ModScope.Flags) then
|
|
if not (pmsfAssertSearched in ModScope.Flags) then
|
|
- FindAssertExceptionConstructors(Params);
|
|
|
|
|
|
+ FindAssertExceptionConstructors(nil); // no ErrorEl
|
|
if ModScope.AssertClass=nil then exit;
|
|
if ModScope.AssertClass=nil then exit;
|
|
if length(Params.Params)>1 then
|
|
if length(Params.Params)>1 then
|
|
aConstructor:=ModScope.AssertMsgConstructor
|
|
aConstructor:=ModScope.AssertMsgConstructor
|
|
@@ -14790,36 +14846,72 @@ begin
|
|
CreateReference(aConstructor,Params,rraRead);
|
|
CreateReference(aConstructor,Params,rraRead);
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TPasResolver.FindClassTypeAndConstructor(const aUnitName,
|
|
|
|
- aClassName: string; out aClass: TPasClassType; out
|
|
|
|
- aConstructor: TPasConstructor; ErrorEl: TPasElement): boolean;
|
|
|
|
|
|
+function TPasResolver.FindSystemClassType(const aUnitName, aClassName: string;
|
|
|
|
+ ErrorEl: TPasElement): TPasClassType;
|
|
var
|
|
var
|
|
aMod, UtilsMod: TPasModule;
|
|
aMod, UtilsMod: TPasModule;
|
|
SectionScope: TPasSectionScope;
|
|
SectionScope: TPasSectionScope;
|
|
Identifier: TPasIdentifier;
|
|
Identifier: TPasIdentifier;
|
|
El: TPasElement;
|
|
El: TPasElement;
|
|
- ClassScope: TPasClassScope;
|
|
|
|
begin
|
|
begin
|
|
- Result:=false;
|
|
|
|
- aClass:=nil;
|
|
|
|
- aConstructor:=nil;
|
|
|
|
|
|
+ Result:=nil;
|
|
|
|
|
|
// find unit in uses clauses
|
|
// find unit in uses clauses
|
|
aMod:=RootElement;
|
|
aMod:=RootElement;
|
|
UtilsMod:=FindUsedUnit(aUnitName,aMod);
|
|
UtilsMod:=FindUsedUnit(aUnitName,aMod);
|
|
- if UtilsMod=nil then exit;
|
|
|
|
|
|
+ if UtilsMod=nil then
|
|
|
|
+ if ErrorEl<>nil then
|
|
|
|
+ RaiseIdentifierNotFound(20200523224738,'unit '+aUnitName,ErrorEl)
|
|
|
|
+ else
|
|
|
|
+ exit;
|
|
|
|
|
|
// find class in interface
|
|
// find class in interface
|
|
- if UtilsMod.InterfaceSection=nil then exit;
|
|
|
|
|
|
+ if UtilsMod.InterfaceSection=nil then
|
|
|
|
+ if ErrorEl<>nil then
|
|
|
|
+ RaiseIdentifierNotFound(20200523224831,aUnitName+'.'+aClassName,ErrorEl)
|
|
|
|
+ else
|
|
|
|
+ exit;
|
|
SectionScope:=NoNil(UtilsMod.InterfaceSection.CustomData) as TPasSectionScope;
|
|
SectionScope:=NoNil(UtilsMod.InterfaceSection.CustomData) as TPasSectionScope;
|
|
Identifier:=SectionScope.FindLocalIdentifier(aClassName);
|
|
Identifier:=SectionScope.FindLocalIdentifier(aClassName);
|
|
- if Identifier=nil then exit;
|
|
|
|
|
|
+ if Identifier=nil then
|
|
|
|
+ if ErrorEl<>nil then
|
|
|
|
+ RaiseIdentifierNotFound(20200523224841,aUnitName+'.'+aClassName,ErrorEl)
|
|
|
|
+ else
|
|
|
|
+ exit;
|
|
El:=Identifier.Element;
|
|
El:=Identifier.Element;
|
|
if not (El is TPasClassType) then
|
|
if not (El is TPasClassType) then
|
|
- RaiseXExpectedButYFound(20180119172517,'class '+aClassName,GetElementTypeName(El),ErrorEl);
|
|
|
|
- if TPasClassType(El).ObjKind<>okClass then
|
|
|
|
- RaiseXExpectedButYFound(20180321163200,'class '+aClassName,GetElementTypeName(El),ErrorEl);
|
|
|
|
- aClass:=TPasClassType(El);
|
|
|
|
|
|
+ if ErrorEl<>nil then
|
|
|
|
+ RaiseXExpectedButYFound(20180119172517,'class '+aClassName,GetElementTypeName(El),ErrorEl)
|
|
|
|
+ else
|
|
|
|
+ exit;
|
|
|
|
+ Result:=TPasClassType(El);
|
|
|
|
+
|
|
|
|
+ if Result.IsForward then
|
|
|
|
+ if ErrorEl<>nil then
|
|
|
|
+ RaiseXExpectedButYFound(20200523225546,'class '+aClassName,'forward '+GetTypeDescription(Result,true),ErrorEl)
|
|
|
|
+ else
|
|
|
|
+ exit;
|
|
|
|
+
|
|
|
|
+ if Result.ObjKind<>okClass then
|
|
|
|
+ if ErrorEl<>nil then
|
|
|
|
+ RaiseXExpectedButYFound(20180321163200,'class '+aClassName,GetTypeDescription(Result,true),ErrorEl)
|
|
|
|
+ else
|
|
|
|
+ exit;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TPasResolver.FindSystemClassTypeAndConstructor(const aUnitName,
|
|
|
|
+ aClassName: string; out aClass: TPasClassType; out
|
|
|
|
+ aConstructor: TPasConstructor; ErrorEl: TPasElement): boolean;
|
|
|
|
+var
|
|
|
|
+ Identifier: TPasIdentifier;
|
|
|
|
+ ClassScope: TPasClassScope;
|
|
|
|
+begin
|
|
|
|
+ Result:=false;
|
|
|
|
+ aClass:=nil;
|
|
|
|
+ aConstructor:=nil;
|
|
|
|
+
|
|
|
|
+ aClass:=FindSystemClassType(aUnitName,aClassName,ErrorEl);
|
|
|
|
+ if aClass=nil then exit;
|
|
|
|
|
|
ClassScope:=NoNil(aClass.CustomData) as TPasClassScope;
|
|
ClassScope:=NoNil(aClass.CustomData) as TPasClassScope;
|
|
repeat
|
|
repeat
|
|
@@ -14837,6 +14929,9 @@ begin
|
|
ClassScope:=ClassScope.AncestorScope;
|
|
ClassScope:=ClassScope.AncestorScope;
|
|
until ClassScope=nil;
|
|
until ClassScope=nil;
|
|
aConstructor:=nil;
|
|
aConstructor:=nil;
|
|
|
|
+
|
|
|
|
+ if ErrorEl<>nil then
|
|
|
|
+ RaiseIdentifierNotFound(20200523224856,'constructor '+aClassName,ErrorEl);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TPasResolver.FindAssertExceptionConstructors(ErrorEl: TPasElement);
|
|
procedure TPasResolver.FindAssertExceptionConstructors(ErrorEl: TPasElement);
|
|
@@ -14854,9 +14949,9 @@ begin
|
|
ModScope:=aMod.CustomData as TPasModuleScope;
|
|
ModScope:=aMod.CustomData as TPasModuleScope;
|
|
if pmsfAssertSearched in ModScope.Flags then exit;
|
|
if pmsfAssertSearched in ModScope.Flags then exit;
|
|
Include(ModScope.Flags,pmsfAssertSearched);
|
|
Include(ModScope.Flags,pmsfAssertSearched);
|
|
-
|
|
|
|
- FindClassTypeAndConstructor('sysutils','EAssertionFailed',aClass,aConstructor,ErrorEl);
|
|
|
|
- if aClass=nil then exit;
|
|
|
|
|
|
+ FindSystemClassTypeAndConstructor('sysutils','EAssertionFailed',aClass,aConstructor,ErrorEl);
|
|
|
|
+ if aClass=nil then
|
|
|
|
+ exit;
|
|
ClassScope:=NoNil(aClass.CustomData) as TPasClassScope;
|
|
ClassScope:=NoNil(aClass.CustomData) as TPasClassScope;
|
|
ModScope.AssertClass:=aClass;
|
|
ModScope.AssertClass:=aClass;
|
|
repeat
|
|
repeat
|
|
@@ -14902,7 +14997,7 @@ begin
|
|
if pmsfRangeErrorSearched in ModScope.Flags then exit;
|
|
if pmsfRangeErrorSearched in ModScope.Flags then exit;
|
|
Include(ModScope.Flags,pmsfRangeErrorSearched);
|
|
Include(ModScope.Flags,pmsfRangeErrorSearched);
|
|
|
|
|
|
- FindClassTypeAndConstructor('sysutils','ERangeError',aClass,aConstructor,ErrorEl);
|
|
|
|
|
|
+ FindSystemClassTypeAndConstructor('sysutils','ERangeError',aClass,aConstructor,ErrorEl);
|
|
ModScope.RangeErrorClass:=aClass;
|
|
ModScope.RangeErrorClass:=aClass;
|
|
ModScope.RangeErrorConstructor:=aConstructor;
|
|
ModScope.RangeErrorConstructor:=aConstructor;
|
|
end;
|
|
end;
|
|
@@ -17428,6 +17523,9 @@ var
|
|
i: Integer;
|
|
i: Integer;
|
|
GenScope: TPasGenericScope;
|
|
GenScope: TPasGenericScope;
|
|
begin
|
|
begin
|
|
|
|
+ if GenEl.VarArgsType<>nil then
|
|
|
|
+ RaiseNotYetImplemented(20200524214316,GenEl,'specialize varargs of type');
|
|
|
|
+
|
|
if GenEl.GenericTemplateTypes<>nil then
|
|
if GenEl.GenericTemplateTypes<>nil then
|
|
begin
|
|
begin
|
|
GenScope:=TPasGenericScope(PushScope(SpecEl,TPasProcTypeScope));
|
|
GenScope:=TPasGenericScope(PushScope(SpecEl,TPasProcTypeScope));
|
|
@@ -17450,7 +17548,7 @@ begin
|
|
for i:=0 to SpecEl.Args.Count-1 do
|
|
for i:=0 to SpecEl.Args.Count-1 do
|
|
FinishArgument(TPasArgument(SpecEl.Args[i]));
|
|
FinishArgument(TPasArgument(SpecEl.Args[i]));
|
|
|
|
|
|
- // properties
|
|
|
|
|
|
+ // calling convention and proc type modifiers
|
|
SpecEl.CallingConvention:=GenEl.CallingConvention;
|
|
SpecEl.CallingConvention:=GenEl.CallingConvention;
|
|
SpecEl.Modifiers:=GenEl.Modifiers;
|
|
SpecEl.Modifiers:=GenEl.Modifiers;
|
|
|
|
|
|
@@ -18435,7 +18533,7 @@ begin
|
|
exit(cIncompatible);
|
|
exit(cIncompatible);
|
|
end;
|
|
end;
|
|
ResultEl:=TPasFunctionType(CtxProc.ProcType).ResultEl;
|
|
ResultEl:=TPasFunctionType(CtxProc.ProcType).ResultEl;
|
|
- ComputeElement(ResultEl,ResultResolved,[rcType]);
|
|
|
|
|
|
+ ComputeResultElement(ResultEl,ResultResolved,[],Expr);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
@@ -21961,7 +22059,7 @@ function TPasResolver.PushTemplateDotScope(TemplType: TPasGenericTemplateType;
|
|
if Result<>nil then
|
|
if Result<>nil then
|
|
RaiseNotYetImplemented(20190831005217,TemplType);
|
|
RaiseNotYetImplemented(20190831005217,TemplType);
|
|
|
|
|
|
- if not FindClassTypeAndConstructor('system','tobject',aClass,aConstructor,ErrorEl) then
|
|
|
|
|
|
+ if not FindSystemClassTypeAndConstructor('system','tobject',aClass,aConstructor,ErrorEl) then
|
|
RaiseIdentifierNotFound(20190831002421,'system.TObject.Create()',ErrorEl);
|
|
RaiseIdentifierNotFound(20190831002421,'system.TObject.Create()',ErrorEl);
|
|
DotClassScope:=TPasDotClassScope.Create;
|
|
DotClassScope:=TPasDotClassScope.Create;
|
|
Result:=DotClassScope;
|
|
Result:=DotClassScope;
|
|
@@ -23250,8 +23348,8 @@ begin
|
|
end;
|
|
end;
|
|
if Proc1 is TPasFunctionType then
|
|
if Proc1 is TPasFunctionType then
|
|
begin
|
|
begin
|
|
- ComputeElement(TPasFunctionType(Proc1).ResultEl.ResultType,Result1Resolved,[rcType]);
|
|
|
|
- ComputeElement(TPasFunctionType(Proc2).ResultEl.ResultType,Result2Resolved,[rcType]);
|
|
|
|
|
|
+ ComputeResultElement(TPasFunctionType(Proc1).ResultEl,Result1Resolved,[]);
|
|
|
|
+ ComputeResultElement(TPasFunctionType(Proc2).ResultEl,Result2Resolved,[]);
|
|
if (Result1Resolved.BaseType<>Result2Resolved.BaseType)
|
|
if (Result1Resolved.BaseType<>Result2Resolved.BaseType)
|
|
or not IsSameType(Result1Resolved.HiTypeEl,Result2Resolved.HiTypeEl,prraSimple) then
|
|
or not IsSameType(Result1Resolved.HiTypeEl,Result2Resolved.HiTypeEl,prraSimple) then
|
|
begin
|
|
begin
|
|
@@ -23260,6 +23358,8 @@ begin
|
|
[],Result1Resolved,Result2Resolved,ErrorEl);
|
|
[],Result1Resolved,Result2Resolved,ErrorEl);
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
+ if Proc1.IsAsync<>Proc2.IsAsync then
|
|
|
|
+ RaiseMsg(20200524112519,nXModifierMismatchY,sXModifierMismatchY,['procedure type','async'],ErrorEl);
|
|
end;
|
|
end;
|
|
Result:=true;
|
|
Result:=true;
|
|
end;
|
|
end;
|
|
@@ -26781,8 +26881,8 @@ procedure TPasResolver.ComputeElement(El: TPasElement; out
|
|
// proc
|
|
// proc
|
|
if rcNoImplicitProc in Flags then
|
|
if rcNoImplicitProc in Flags then
|
|
begin
|
|
begin
|
|
- if rcSetReferenceFlags in Flags then
|
|
|
|
- Include(Ref.Flags,rrfNoImplicitCallWithoutParams);
|
|
|
|
|
|
+ if rcSetReferenceFlags in Flags then
|
|
|
|
+ Include(Ref.Flags,rrfNoImplicitCallWithoutParams);
|
|
end
|
|
end
|
|
else if [rcConstant,rcType]*Flags=[] then
|
|
else if [rcConstant,rcType]*Flags=[] then
|
|
begin
|
|
begin
|
|
@@ -26794,8 +26894,8 @@ procedure TPasResolver.ComputeElement(El: TPasElement; out
|
|
if ResolvedEl.IdentEl is TPasFunction then
|
|
if ResolvedEl.IdentEl is TPasFunction then
|
|
begin
|
|
begin
|
|
// function => return result
|
|
// function => return result
|
|
- ComputeElement(TPasFunction(ResolvedEl.IdentEl).FuncType.ResultEl,
|
|
|
|
- ResolvedEl,Flags+[rcType],StartEl);
|
|
|
|
|
|
+ ComputeResultElement(TPasFunction(ResolvedEl.IdentEl).FuncType.ResultEl,
|
|
|
|
+ ResolvedEl,Flags+[rcCall],StartEl);
|
|
end
|
|
end
|
|
else if (ResolvedEl.IdentEl.ClassType=TPasConstructor) then
|
|
else if (ResolvedEl.IdentEl.ClassType=TPasConstructor) then
|
|
begin
|
|
begin
|
|
@@ -26808,7 +26908,10 @@ procedure TPasResolver.ComputeElement(El: TPasElement; out
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
if rcSetReferenceFlags in Flags then
|
|
if rcSetReferenceFlags in Flags then
|
|
|
|
+ begin
|
|
|
|
+ Exclude(Ref.Flags,rrfNoImplicitCallWithoutParams);
|
|
Include(Ref.Flags,rrfImplicitCallWithoutParams);
|
|
Include(Ref.Flags,rrfImplicitCallWithoutParams);
|
|
|
|
+ end;
|
|
Include(ResolvedEl.Flags,rrfCanBeStatement);
|
|
Include(ResolvedEl.Flags,rrfCanBeStatement);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -26818,8 +26921,8 @@ procedure TPasResolver.ComputeElement(El: TPasElement; out
|
|
// proc type
|
|
// proc type
|
|
if [rcNoImplicitProc,rcNoImplicitProcType]*Flags<>[] then
|
|
if [rcNoImplicitProc,rcNoImplicitProcType]*Flags<>[] then
|
|
begin
|
|
begin
|
|
- if rcSetReferenceFlags in Flags then
|
|
|
|
- Include(Ref.Flags,rrfNoImplicitCallWithoutParams);
|
|
|
|
|
|
+ if rcSetReferenceFlags in Flags then
|
|
|
|
+ Include(Ref.Flags,rrfNoImplicitCallWithoutParams);
|
|
end
|
|
end
|
|
else if [rcConstant,rcType]*Flags=[] then
|
|
else if [rcConstant,rcType]*Flags=[] then
|
|
begin
|
|
begin
|
|
@@ -26830,15 +26933,18 @@ procedure TPasResolver.ComputeElement(El: TPasElement; out
|
|
// parameter less proc type -> implicit call possible
|
|
// parameter less proc type -> implicit call possible
|
|
if ResolvedEl.LoTypeEl is TPasFunctionType then
|
|
if ResolvedEl.LoTypeEl is TPasFunctionType then
|
|
// function => return result
|
|
// function => return result
|
|
- ComputeElement(TPasFunctionType(ResolvedEl.LoTypeEl).ResultEl,
|
|
|
|
- ResolvedEl,Flags+[rcType],StartEl)
|
|
|
|
|
|
+ ComputeResultElement(TPasFunctionType(ResolvedEl.LoTypeEl).ResultEl,
|
|
|
|
+ ResolvedEl,Flags+[rcCall],StartEl)
|
|
else if ParentNeedsExprResult(Expr) then
|
|
else if ParentNeedsExprResult(Expr) then
|
|
begin
|
|
begin
|
|
// a procedure has no result
|
|
// a procedure has no result
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
if rcSetReferenceFlags in Flags then
|
|
if rcSetReferenceFlags in Flags then
|
|
|
|
+ begin
|
|
|
|
+ Exclude(Ref.Flags,rrfNoImplicitCallWithoutParams);
|
|
Include(Ref.Flags,rrfImplicitCallWithoutParams);
|
|
Include(Ref.Flags,rrfImplicitCallWithoutParams);
|
|
|
|
+ end;
|
|
Include(ResolvedEl.Flags,rrfCanBeStatement);
|
|
Include(ResolvedEl.Flags,rrfCanBeStatement);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -26867,8 +26973,8 @@ procedure TPasResolver.ComputeElement(El: TPasElement; out
|
|
if Proc is TPasFunction then
|
|
if Proc is TPasFunction then
|
|
begin
|
|
begin
|
|
// function => return result
|
|
// function => return result
|
|
- ComputeElement(TPasFunction(Proc).FuncType.ResultEl,
|
|
|
|
- ResolvedEl,Flags+[rcType],StartEl);
|
|
|
|
|
|
+ ComputeResultElement(TPasFunction(Proc).FuncType.ResultEl,
|
|
|
|
+ ResolvedEl,Flags+[rcCall],StartEl);
|
|
Exclude(ResolvedEl.Flags,rrfWritable);
|
|
Exclude(ResolvedEl.Flags,rrfWritable);
|
|
end
|
|
end
|
|
else if (Proc.ClassType=TPasConstructor)
|
|
else if (Proc.ClassType=TPasConstructor)
|
|
@@ -26883,7 +26989,10 @@ procedure TPasResolver.ComputeElement(El: TPasElement; out
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
if rcSetReferenceFlags in Flags then
|
|
if rcSetReferenceFlags in Flags then
|
|
|
|
+ begin
|
|
|
|
+ Exclude(Ref.Flags,rrfNoImplicitCallWithoutParams);
|
|
Include(Ref.Flags,rrfImplicitCallWithoutParams);
|
|
Include(Ref.Flags,rrfImplicitCallWithoutParams);
|
|
|
|
+ end;
|
|
Include(ResolvedEl.Flags,rrfCanBeStatement);
|
|
Include(ResolvedEl.Flags,rrfCanBeStatement);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -27230,9 +27339,7 @@ begin
|
|
begin
|
|
begin
|
|
if rcConstant in Flags then
|
|
if rcConstant in Flags then
|
|
RaiseConstantExprExp(20170216152746,StartEl);
|
|
RaiseConstantExprExp(20170216152746,StartEl);
|
|
- ComputeElement(TPasResultElement(El).ResultType,ResolvedEl,Flags+[rcType],StartEl);
|
|
|
|
- ResolvedEl.IdentEl:=El;
|
|
|
|
- ResolvedEl.Flags:=[rrfReadable,rrfWritable];
|
|
|
|
|
|
+ ComputeResultElement(TPasResultElement(El),ResolvedEl,Flags,StartEl);
|
|
end
|
|
end
|
|
else if ElClass=TPasUsesUnit then
|
|
else if ElClass=TPasUsesUnit then
|
|
begin
|
|
begin
|
|
@@ -27304,6 +27411,17 @@ begin
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TPasResolver.ComputeResultElement(El: TPasResultElement; out
|
|
|
|
+ ResolvedEl: TPasResolverResult; Flags: TPasResolverComputeFlags;
|
|
|
|
+ StartEl: TPasElement);
|
|
|
|
+begin
|
|
|
|
+ if El.ResultType=nil then
|
|
|
|
+ RaiseNotYetImplemented(20200524214458,El);
|
|
|
|
+ ComputeElement(El.ResultType,ResolvedEl,Flags+[rcType,rcNoImplicitProc],StartEl);
|
|
|
|
+ ResolvedEl.IdentEl:=El;
|
|
|
|
+ ResolvedEl.Flags:=[rrfReadable,rrfWritable];
|
|
|
|
+end;
|
|
|
|
+
|
|
function TPasResolver.Eval(Expr: TPasExpr; Flags: TResEvalFlags;
|
|
function TPasResolver.Eval(Expr: TPasExpr; Flags: TResEvalFlags;
|
|
Store: boolean): TResEvalValue;
|
|
Store: boolean): TResEvalValue;
|
|
// Important: Caller must free result with ReleaseEvalValue(Result)
|
|
// Important: Caller must free result with ReleaseEvalValue(Result)
|