Browse Source

fcl-passrc: property accessor: allow alias types

git-svn-id: trunk@35883 -
Mattias Gaertner 8 years ago
parent
commit
21f1fd04e1
2 changed files with 25 additions and 14 deletions
  1. 23 13
      packages/fcl-passrc/src/pasresolver.pp
  2. 2 1
      packages/fcl-passrc/tests/tcresolver.pas

+ 23 - 13
packages/fcl-passrc/src/pasresolver.pp

@@ -1304,7 +1304,7 @@ type
       const TheBaseProcs: TResolverBuiltInProcs = bfAllStandardProcs); virtual;
       const TheBaseProcs: TResolverBuiltInProcs = bfAllStandardProcs); virtual;
     function AddBaseType(const aName: string; Typ: TResolverBaseType): TResElDataBaseType;
     function AddBaseType(const aName: string; Typ: TResolverBaseType): TResElDataBaseType;
     function AddCustomBaseType(const aName: string; aClass: TResElDataBaseTypeClass): TPasUnresolvedSymbolRef;
     function AddCustomBaseType(const aName: string; aClass: TResElDataBaseTypeClass): TPasUnresolvedSymbolRef;
-    function IsBaseType(aType: TPasType; BaseType: TResolverBaseType): boolean;
+    function IsBaseType(aType: TPasType; BaseType: TResolverBaseType; ResolveAlias: boolean = false): boolean;
     function AddBuiltInProc(const aName: string; Signature: string;
     function AddBuiltInProc(const aName: string; Signature: string;
       const GetCallCompatibility: TOnGetCallCompatibility;
       const GetCallCompatibility: TOnGetCallCompatibility;
       const GetCallResult: TOnGetCallResult;
       const GetCallResult: TOnGetCallResult;
@@ -1360,7 +1360,7 @@ type
     procedure ComputeElement(El: TPasElement; out ResolvedEl: TPasResolverResult;
     procedure ComputeElement(El: TPasElement; out ResolvedEl: TPasResolverResult;
       Flags: TPasResolverComputeFlags; StartEl: TPasElement = nil);
       Flags: TPasResolverComputeFlags; StartEl: TPasElement = nil);
     // checking compatibilility
     // checking compatibilility
-    function IsSameType(TypeA, TypeB: TPasType): boolean; // check if it is exactly the same
+    function IsSameType(TypeA, TypeB: TPasType; ResolveAlias: boolean = false): boolean; // check if it is exactly the same
     function CheckCallProcCompatibility(ProcType: TPasProcedureType;
     function CheckCallProcCompatibility(ProcType: TPasProcedureType;
       Params: TParamsExpr; RaiseOnError: boolean): integer;
       Params: TParamsExpr; RaiseOnError: boolean): integer;
     function CheckCallPropertyCompatibility(PropEl: TPasProperty;
     function CheckCallPropertyCompatibility(PropEl: TPasProperty;
@@ -3897,7 +3897,7 @@ begin
       begin
       begin
       if PropEl.Args.Count>0 then
       if PropEl.Args.Count>0 then
         RaiseXExpectedButYFound(20170216151823,'function',AccEl.ElementTypeName,PropEl.ReadAccessor);
         RaiseXExpectedButYFound(20170216151823,'function',AccEl.ElementTypeName,PropEl.ReadAccessor);
-      if TPasVariable(AccEl).VarType<>PropType then
+      if not IsSameType(TPasVariable(AccEl).VarType,PropType,true) then
         RaiseIncompatibleType(20170216151826,nIncompatibleTypesGotExpected,
         RaiseIncompatibleType(20170216151826,nIncompatibleTypesGotExpected,
           [],PropType,TPasVariable(AccEl).VarType,PropEl.ReadAccessor);
           [],PropType,TPasVariable(AccEl).VarType,PropEl.ReadAccessor);
       if (vmClass in PropEl.VarModifiers)<>(vmClass in TPasVariable(AccEl).VarModifiers) then
       if (vmClass in PropEl.VarModifiers)<>(vmClass in TPasVariable(AccEl).VarModifiers) then
@@ -3927,7 +3927,7 @@ begin
         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) then
+      if not IsSameType(ResultType,PropType,true) then
         RaiseXExpectedButYFound(20170216151844,'function result '+GetTypeDescription(PropType,true),
         RaiseXExpectedButYFound(20170216151844,'function result '+GetTypeDescription(PropType,true),
           GetTypeDescription(ResultType,true),PropEl.ReadAccessor);
           GetTypeDescription(ResultType,true),PropEl.ReadAccessor);
       // check args
       // check args
@@ -3947,7 +3947,7 @@ begin
       begin
       begin
       if PropEl.Args.Count>0 then
       if PropEl.Args.Count>0 then
         RaiseXExpectedButYFound(20170216151852,'procedure',AccEl.ElementTypeName,PropEl.WriteAccessor);
         RaiseXExpectedButYFound(20170216151852,'procedure',AccEl.ElementTypeName,PropEl.WriteAccessor);
-      if TPasVariable(AccEl).VarType<>PropType then
+      if not IsSameType(TPasVariable(AccEl).VarType,PropType,true) then
         RaiseIncompatibleType(20170216151855,nIncompatibleTypesGotExpected,
         RaiseIncompatibleType(20170216151855,nIncompatibleTypesGotExpected,
           [],PropType,TPasVariable(AccEl).VarType,PropEl.WriteAccessor);
           [],PropType,TPasVariable(AccEl).VarType,PropEl.WriteAccessor);
       if (vmClass in PropEl.VarModifiers)<>(vmClass in TPasVariable(AccEl).VarModifiers) then
       if (vmClass in PropEl.VarModifiers)<>(vmClass in TPasVariable(AccEl).VarModifiers) then
@@ -3986,7 +3986,7 @@ begin
         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]],PropEl.WriteAccessor);
-      if Arg.ArgType<>PropType then
+      if not IsSameType(Arg.ArgType,PropType,true) then
         RaiseIncompatibleType(20170216151919,nIncompatibleTypeArgNo,
         RaiseIncompatibleType(20170216151919,nIncompatibleTypeArgNo,
           [IntToStr(PropArgCount+1)],Arg.ArgType,PropType,PropEl.WriteAccessor);
           [IntToStr(PropArgCount+1)],Arg.ArgType,PropType,PropEl.WriteAccessor);
       end
       end
@@ -4007,8 +4007,10 @@ begin
       begin
       begin
       if PropEl.IndexExpr<>nil then
       if PropEl.IndexExpr<>nil then
         RaiseNotYetImplemented(20170409214006,PropEl.StoredAccessor,'stored with index');
         RaiseNotYetImplemented(20170409214006,PropEl.StoredAccessor,'stored with index');
-      TypeEl:=ResolveAliasType(TPasVariable(AccEl).VarType);
-      if not IsBaseType(TypeEl,btBoolean) then
+      TypeEl:=TPasVariable(AccEl).VarType;
+      // ToDo: TypeEl=nil  TPasConst false/true
+      TypeEl:=ResolveAliasType(TypeEl);
+      if not IsBaseType(TypeEl,btBoolean,true) then
         RaiseIncompatibleType(20170409214300,nIncompatibleTypesGotExpected,
         RaiseIncompatibleType(20170409214300,nIncompatibleTypesGotExpected,
           [],TypeEl,BaseTypes[btBoolean],PropEl.StoredAccessor);
           [],TypeEl,BaseTypes[btBoolean],PropEl.StoredAccessor);
       if (vmClass in PropEl.VarModifiers)<>(vmClass in TPasVariable(AccEl).VarModifiers) then
       if (vmClass in PropEl.VarModifiers)<>(vmClass in TPasVariable(AccEl).VarModifiers) then
@@ -4025,7 +4027,7 @@ begin
         RaiseXExpectedButYFound(20170216151925,'function',Proc.ElementTypeName,PropEl.StoredAccessor);
         RaiseXExpectedButYFound(20170216151925,'function',Proc.ElementTypeName,PropEl.StoredAccessor);
       // check function result type
       // check function result type
       ResultType:=TPasFunction(Proc).FuncType.ResultEl.ResultType;
       ResultType:=TPasFunction(Proc).FuncType.ResultEl.ResultType;
-      if not IsBaseType(ResultType,btBoolean) then
+      if not IsBaseType(ResultType,btBoolean,true) then
         RaiseXExpectedButYFound(20170216151929,'function: boolean',
         RaiseXExpectedButYFound(20170216151929,'function: boolean',
           'function:'+GetTypeDescription(ResultType),PropEl.StoredAccessor);
           'function:'+GetTypeDescription(ResultType),PropEl.StoredAccessor);
       // check arg count
       // check arg count
@@ -8670,11 +8672,13 @@ begin
   FDefaultScope.AddIdentifier(aName,Result,pikBaseType);
   FDefaultScope.AddIdentifier(aName,Result,pikBaseType);
 end;
 end;
 
 
-function TPasResolver.IsBaseType(aType: TPasType; BaseType: TResolverBaseType
-  ): boolean;
+function TPasResolver.IsBaseType(aType: TPasType; BaseType: TResolverBaseType;
+  ResolveAlias: boolean): boolean;
 begin
 begin
   Result:=false;
   Result:=false;
   if aType=nil then exit;
   if aType=nil then exit;
+  if ResolveAlias then
+    aType:=ResolveAliasType(aType);
   if aType.ClassType<>TPasUnresolvedSymbolRef then exit;
   if aType.ClassType<>TPasUnresolvedSymbolRef then exit;
   Result:=CompareText(aType.Name,BaseTypeNames[BaseType])=0;
   Result:=CompareText(aType.Name,BaseTypeNames[BaseType])=0;
 end;
 end;
@@ -11528,9 +11532,15 @@ begin
     RaiseNotYetImplemented(20160922163705,El);
     RaiseNotYetImplemented(20160922163705,El);
 end;
 end;
 
 
-function TPasResolver.IsSameType(TypeA, TypeB: TPasType): boolean;
+function TPasResolver.IsSameType(TypeA, TypeB: TPasType; ResolveAlias: boolean
+  ): boolean;
 begin
 begin
-  if TypeA=nil then exit(false);
+  if (TypeA=nil) or (TypeB=nil) then exit(false);
+  if ResolveAlias then
+    begin
+    TypeA:=ResolveAliasType(TypeA);
+    TypeB:=ResolveAliasType(TypeB);
+    end;
   if TypeA=TypeB then exit(true);
   if TypeA=TypeB then exit(true);
   if (TypeA.ClassType=TPasUnresolvedSymbolRef)
   if (TypeA.ClassType=TPasUnresolvedSymbolRef)
       and (TypeB.ClassType=TPasUnresolvedSymbolRef) then
       and (TypeB.ClassType=TPasUnresolvedSymbolRef) then

+ 2 - 1
packages/fcl-passrc/tests/tcresolver.pas

@@ -6963,10 +6963,11 @@ procedure TTestResolver.TestProperty1;
 begin
 begin
   StartProgram(false);
   StartProgram(false);
   Add('type');
   Add('type');
+  Add('  integer = longint;');
   Add('  {#TOBJ}TObject = class');
   Add('  {#TOBJ}TObject = class');
   Add('  end;');
   Add('  end;');
   Add('  {#A}TClassA = class');
   Add('  {#A}TClassA = class');
-  Add('    {#FB}FB: longint;');
+  Add('    {#FB}FB: integer;');
   Add('    property {#B}B: longint read {@FB}FB write {@FB}FB;');
   Add('    property {#B}B: longint read {@FB}FB write {@FB}FB;');
   Add('  end;');
   Add('  end;');
   Add('var');
   Add('var');