Browse Source

pastojs: override class default property

git-svn-id: trunk@38223 -
Mattias Gaertner 7 years ago
parent
commit
032c8f99a6

+ 13 - 9
packages/pastojs/src/fppas2js.pp

@@ -2513,6 +2513,7 @@ var
   ArgResolved: TPasResolverResult;
   ArgResolved: TPasResolverResult;
   ParentC: TClass;
   ParentC: TClass;
   IndexExpr: TPasExpr;
   IndexExpr: TPasExpr;
+  PropArgs: TFPList;
 begin
 begin
   inherited FinishPropertyOfClass(PropEl);
   inherited FinishPropertyOfClass(PropEl);
 
 
@@ -2535,23 +2536,24 @@ begin
   Setter:=GetPasPropertySetter(PropEl);
   Setter:=GetPasPropertySetter(PropEl);
   SetterIsBracketAccessor:=IsExternalBracketAccessor(Setter);
   SetterIsBracketAccessor:=IsExternalBracketAccessor(Setter);
   IndexExpr:=GetPasPropertyIndex(PropEl);
   IndexExpr:=GetPasPropertyIndex(PropEl);
+  PropArgs:=GetPasPropertyArgs(PropEl);
   if GetterIsBracketAccessor then
   if GetterIsBracketAccessor then
     begin
     begin
-    if (PropEl.Args.Count<>1) or (IndexExpr<>nil) then
+    if (PropArgs.Count<>1) or (IndexExpr<>nil) then
       RaiseMsg(20170403001743,nBracketAccessorOfExternalClassMustHaveOneParameter,
       RaiseMsg(20170403001743,nBracketAccessorOfExternalClassMustHaveOneParameter,
         sBracketAccessorOfExternalClassMustHaveOneParameter,
         sBracketAccessorOfExternalClassMustHaveOneParameter,
         [],PropEl);
         [],PropEl);
     end;
     end;
   if SetterIsBracketAccessor then
   if SetterIsBracketAccessor then
     begin
     begin
-    if (PropEl.Args.Count<>1) or (IndexExpr<>nil) then
+    if (PropArgs.Count<>1) or (IndexExpr<>nil) then
       RaiseMsg(20170403001806,nBracketAccessorOfExternalClassMustHaveOneParameter,
       RaiseMsg(20170403001806,nBracketAccessorOfExternalClassMustHaveOneParameter,
         sBracketAccessorOfExternalClassMustHaveOneParameter,
         sBracketAccessorOfExternalClassMustHaveOneParameter,
         [],PropEl);
         [],PropEl);
     end;
     end;
   if GetterIsBracketAccessor or SetterIsBracketAccessor then
   if GetterIsBracketAccessor or SetterIsBracketAccessor then
     begin
     begin
-    Arg:=TPasArgument(PropEl.Args[0]);
+    Arg:=TPasArgument(PropArgs[0]);
     if not (Arg.Access in [argDefault,argConst]) then
     if not (Arg.Access in [argDefault,argConst]) then
       RaiseMsg(20170403090225,nXExpectedButYFound,sXExpectedButYFound,
       RaiseMsg(20170403090225,nXExpectedButYFound,sXExpectedButYFound,
         ['default or "const"',AccessNames[Arg.Access]],PropEl);
         ['default or "const"',AccessNames[Arg.Access]],PropEl);
@@ -5670,7 +5672,7 @@ var
       exit(false);
       exit(false);
     Result:=true;
     Result:=true;
     // bracket accessor of external class
     // bracket accessor of external class
-    if Prop.Args.Count<>1 then
+    if AContext.Resolver.GetPasPropertyArgs(Prop).Count<>1 then
       RaiseInconsistency(20170403003753);
       RaiseInconsistency(20170403003753);
     // bracket accessor of external class  -> create  PathEl[param]
     // bracket accessor of external class  -> create  PathEl[param]
     Bracket:=TJSBracketMemberExpression(CreateElement(TJSBracketMemberExpression,El.Params[0]));
     Bracket:=TJSBracketMemberExpression(CreateElement(TJSBracketMemberExpression,El.Params[0]));
@@ -5732,6 +5734,7 @@ var
     OldAccess: TCtxAccess;
     OldAccess: TCtxAccess;
     IndexExpr: TPasExpr;
     IndexExpr: TPasExpr;
     Value: TResEvalValue;
     Value: TResEvalValue;
+    PropArgs: TFPList;
   begin
   begin
     Result:=nil;
     Result:=nil;
     AssignContext:=nil;
     AssignContext:=nil;
@@ -5762,18 +5765,19 @@ var
       Elements:=Call.Args.Elements;
       Elements:=Call.Args.Elements;
       OldAccess:=ArgContext.Access;
       OldAccess:=ArgContext.Access;
       // add params
       // add params
+      PropArgs:=AContext.Resolver.GetPasPropertyArgs(Prop);
       i:=0;
       i:=0;
-      while i<Prop.Args.Count do
+      while i<PropArgs.Count do
         begin
         begin
-        TargetArg:=TPasArgument(Prop.Args[i]);
+        TargetArg:=TPasArgument(PropArgs[i]);
         Arg:=CreateProcCallArg(El.Params[i],TargetArg,ArgContext);
         Arg:=CreateProcCallArg(El.Params[i],TargetArg,ArgContext);
         Elements.AddElement.Expr:=Arg;
         Elements.AddElement.Expr:=Arg;
         inc(i);
         inc(i);
         end;
         end;
       // fill up default values
       // fill up default values
-      while i<Prop.Args.Count do
+      while i<PropArgs.Count do
         begin
         begin
-        TargetArg:=TPasArgument(Prop.Args[i]);
+        TargetArg:=TPasArgument(PropArgs[i]);
         if TargetArg.ValueExpr=nil then
         if TargetArg.ValueExpr=nil then
           begin
           begin
           {$IFDEF VerbosePas2JS}
           {$IFDEF VerbosePas2JS}
@@ -5927,7 +5931,7 @@ begin
     // astring[]
     // astring[]
     ConvertStringBracket(ResolvedEl)
     ConvertStringBracket(ResolvedEl)
   else if (ResolvedEl.IdentEl is TPasProperty)
   else if (ResolvedEl.IdentEl is TPasProperty)
-      and (TPasProperty(ResolvedEl.IdentEl).Args.Count>0) then
+      and (AContext.Resolver.GetPasPropertyArgs(TPasProperty(ResolvedEl.IdentEl)).Count>0) then
     // aproperty[]
     // aproperty[]
     ConvertIndexedProperty(TPasProperty(ResolvedEl.IdentEl),AContext)
     ConvertIndexedProperty(TPasProperty(ResolvedEl.IdentEl),AContext)
   else if ResolvedEl.BaseType=btContext then
   else if ResolvedEl.BaseType=btContext then

+ 10 - 0
packages/pastojs/src/pas2jsfiler.pp

@@ -395,6 +395,16 @@ const
     'GrpOverload'
     'GrpOverload'
     );
     );
 
 
+  PJUResolvedRefAccessNames: array[TResolvedRefAccess] of string = (
+    'None',
+    'Read',
+    'Assign',
+    'ReadAndAssign',
+    'VarParam',
+    'OutParam',
+    'ParamToUnknownProc'
+    );
+
 type
 type
   { TPJUInitialFlags }
   { TPJUInitialFlags }
 
 

+ 174 - 37
packages/pastojs/tests/tcfiler.pas

@@ -50,13 +50,25 @@ type
     procedure CheckRestoredSection(const Path: string; Orig, Rest: TPasSection); virtual;
     procedure CheckRestoredSection(const Path: string; Orig, Rest: TPasSection); virtual;
     procedure CheckRestoredModule(const Path: string; Orig, Rest: TPasModule); virtual;
     procedure CheckRestoredModule(const Path: string; Orig, Rest: TPasModule); virtual;
     procedure CheckRestoredScopeReference(const Path: string; Orig, Rest: TPasScope); virtual;
     procedure CheckRestoredScopeReference(const Path: string; Orig, Rest: TPasScope); virtual;
+    procedure CheckRestoredElementBase(const Path: string; Orig, Rest: TPasElementBase); virtual;
+    procedure CheckRestoredResolveData(const Path: string; Orig, Rest: TResolveData); virtual;
+    procedure CheckRestoredPasScope(const Path: string; Orig, Rest: TPasScope); virtual;
     procedure CheckRestoredModuleScope(const Path: string; Orig, Rest: TPasModuleScope); virtual;
     procedure CheckRestoredModuleScope(const Path: string; Orig, Rest: TPasModuleScope); virtual;
     procedure CheckRestoredIdentifierScope(const Path: string; Orig, Rest: TPasIdentifierScope); virtual;
     procedure CheckRestoredIdentifierScope(const Path: string; Orig, Rest: TPasIdentifierScope); virtual;
     procedure CheckRestoredSectionScope(const Path: string; Orig, Rest: TPasSectionScope); virtual;
     procedure CheckRestoredSectionScope(const Path: string; Orig, Rest: TPasSectionScope); virtual;
+    procedure CheckRestoredEnumTypeScope(const Path: string; Orig, Rest: TPasEnumTypeScope); virtual;
+    procedure CheckRestoredRecordScope(const Path: string; Orig, Rest: TPasRecordScope); virtual;
+    procedure CheckRestoredClassScope(const Path: string; Orig, Rest: TPas2JSClassScope); virtual;
     procedure CheckRestoredProcScope(const Path: string; Orig, Rest: TPas2JSProcedureScope); virtual;
     procedure CheckRestoredProcScope(const Path: string; Orig, Rest: TPas2JSProcedureScope); virtual;
+    procedure CheckRestoredPropertyScope(const Path: string; Orig, Rest: TPasPropertyScope); virtual;
+    procedure CheckRestoredResolvedReference(const Path: string; Orig, Rest: TResolvedReference); virtual;
     procedure CheckRestoredCustomData(const Path: string; El: TPasElement; Orig, Rest: TObject); virtual;
     procedure CheckRestoredCustomData(const Path: string; El: TPasElement; Orig, Rest: TObject); virtual;
+    procedure CheckRestoredReference(const Path: string; Orig, Rest: TPasElement); virtual;
+    procedure CheckRestoredElOrRef(const Path: string; Orig, OrigProp, Rest, RestProp: TPasElement); virtual;
     procedure CheckRestoredElement(const Path: string; Orig, Rest: TPasElement); virtual;
     procedure CheckRestoredElement(const Path: string; Orig, Rest: TPasElement); virtual;
     procedure CheckRestoredElementList(const Path: string; Orig, Rest: TFPList); virtual;
     procedure CheckRestoredElementList(const Path: string; Orig, Rest: TFPList); virtual;
+    procedure CheckRestoredElRefList(const Path: string; OrigParent: TPasElement;
+      Orig: TFPList; RestParent: TPasElement; Rest: TFPList; AllowInSitu: boolean); virtual;
     procedure CheckRestoredPasExpr(const Path: string; Orig, Rest: TPasExpr); virtual;
     procedure CheckRestoredPasExpr(const Path: string; Orig, Rest: TPasExpr); virtual;
     procedure CheckRestoredUnaryExpr(const Path: string; Orig, Rest: TUnaryExpr); virtual;
     procedure CheckRestoredUnaryExpr(const Path: string; Orig, Rest: TUnaryExpr); virtual;
     procedure CheckRestoredBinaryExpr(const Path: string; Orig, Rest: TBinaryExpr); virtual;
     procedure CheckRestoredBinaryExpr(const Path: string; Orig, Rest: TBinaryExpr); virtual;
@@ -91,7 +103,6 @@ type
     procedure CheckRestoredProperty(const Path: string; Orig, Rest: TPasProperty); virtual;
     procedure CheckRestoredProperty(const Path: string; Orig, Rest: TPasProperty); virtual;
     procedure CheckRestoredProcedure(const Path: string; Orig, Rest: TPasProcedure); virtual;
     procedure CheckRestoredProcedure(const Path: string; Orig, Rest: TPasProcedure); virtual;
     procedure CheckRestoredOperator(const Path: string; Orig, Rest: TPasOperator); virtual;
     procedure CheckRestoredOperator(const Path: string; Orig, Rest: TPasOperator); virtual;
-    procedure CheckRestoredReference(const Path: string; Orig, Rest: TPasElement); virtual;
   public
   public
     property PJUWriter: TPJUWriter read FPJUWriter write FPJUWriter;
     property PJUWriter: TPJUWriter read FPJUWriter write FPJUWriter;
     property PJUReader: TPJUReader read FPJUReader write FPJUReader;
     property PJUReader: TPJUReader read FPJUReader write FPJUReader;
@@ -307,6 +318,25 @@ begin
   CheckRestoredReference(Path+'.Element',Orig.Element,Rest.Element);
   CheckRestoredReference(Path+'.Element',Orig.Element,Rest.Element);
 end;
 end;
 
 
+procedure TCustomTestPrecompile.CheckRestoredElementBase(const Path: string;
+  Orig, Rest: TPasElementBase);
+begin
+  CheckRestoredObject(Path+'.CustomData',Orig.CustomData,Rest.CustomData);
+end;
+
+procedure TCustomTestPrecompile.CheckRestoredResolveData(const Path: string;
+  Orig, Rest: TResolveData);
+begin
+  CheckRestoredElementBase(Path,Orig,Rest);
+end;
+
+procedure TCustomTestPrecompile.CheckRestoredPasScope(const Path: string; Orig,
+  Rest: TPasScope);
+begin
+  CheckRestoredReference(Path+'.VisibilityContext',Orig.VisibilityContext,Rest.VisibilityContext);
+  CheckRestoredResolveData(Path,Orig,Rest);
+end;
+
 procedure TCustomTestPrecompile.CheckRestoredModuleScope(const Path: string;
 procedure TCustomTestPrecompile.CheckRestoredModuleScope(const Path: string;
   Orig, Rest: TPasModuleScope);
   Orig, Rest: TPasModuleScope);
 begin
 begin
@@ -320,6 +350,7 @@ begin
   CheckRestoredReference(Path+'.AssertMsgConstructor',Orig.AssertMsgConstructor,Rest.AssertMsgConstructor);
   CheckRestoredReference(Path+'.AssertMsgConstructor',Orig.AssertMsgConstructor,Rest.AssertMsgConstructor);
   CheckRestoredReference(Path+'.RangeErrorClass',Orig.RangeErrorClass,Rest.RangeErrorClass);
   CheckRestoredReference(Path+'.RangeErrorClass',Orig.RangeErrorClass,Rest.RangeErrorClass);
   CheckRestoredReference(Path+'.RangeErrorConstructor',Orig.RangeErrorConstructor,Rest.RangeErrorConstructor);
   CheckRestoredReference(Path+'.RangeErrorConstructor',Orig.RangeErrorConstructor,Rest.RangeErrorConstructor);
+  CheckRestoredPasScope(Path,Orig,Rest);
 end;
 end;
 
 
 procedure TCustomTestPrecompile.CheckRestoredIdentifierScope(
 procedure TCustomTestPrecompile.CheckRestoredIdentifierScope(
@@ -362,6 +393,7 @@ begin
   finally
   finally
     OrigList.Free;
     OrigList.Free;
   end;
   end;
+  CheckRestoredPasScope(Path,Orig,Rest);
 end;
 end;
 
 
 procedure TCustomTestPrecompile.CheckRestoredSectionScope(const Path: string;
 procedure TCustomTestPrecompile.CheckRestoredSectionScope(const Path: string;
@@ -385,6 +417,38 @@ begin
   CheckRestoredIdentifierScope(Path,Orig,Rest);
   CheckRestoredIdentifierScope(Path,Orig,Rest);
 end;
 end;
 
 
+procedure TCustomTestPrecompile.CheckRestoredEnumTypeScope(const Path: string;
+  Orig, Rest: TPasEnumTypeScope);
+begin
+  CheckRestoredElement(Path+'.CanonicalSet',Orig.CanonicalSet,Rest.CanonicalSet);
+  CheckRestoredIdentifierScope(Path,Orig,Rest);
+end;
+
+procedure TCustomTestPrecompile.CheckRestoredRecordScope(const Path: string;
+  Orig, Rest: TPasRecordScope);
+begin
+  CheckRestoredIdentifierScope(Path,Orig,Rest);
+end;
+
+procedure TCustomTestPrecompile.CheckRestoredClassScope(const Path: string;
+  Orig, Rest: TPas2JSClassScope);
+var
+  i: Integer;
+begin
+  CheckRestoredScopeReference(Path+'.AncestorScope',Orig.AncestorScope,Rest.AncestorScope);
+  CheckRestoredElement(Path+'.CanonicalClassOf',Orig.CanonicalClassOf,Rest.CanonicalClassOf);
+  CheckRestoredReference(Path+'.DirectAncestor',Orig.DirectAncestor,Rest.DirectAncestor);
+  CheckRestoredReference(Path+'.DefaultProperty',Orig.DefaultProperty,Rest.DefaultProperty);
+  if Orig.Flags<>Rest.Flags then
+    Fail(Path+'.Flags');
+  AssertEquals(Path+'.AbstractProcs.length',length(Orig.AbstractProcs),length(Rest.AbstractProcs));
+  for i:=0 to length(Orig.AbstractProcs)-1 do
+    CheckRestoredReference(Path+'.AbstractProcs['+IntToStr(i)+']',Orig.AbstractProcs[i],Rest.AbstractProcs[i]);
+  CheckRestoredReference(Path+'.NewInstanceFunction',Orig.NewInstanceFunction,Rest.NewInstanceFunction);
+
+  CheckRestoredIdentifierScope(Path,Orig,Rest);
+end;
+
 procedure TCustomTestPrecompile.CheckRestoredProcScope(const Path: string;
 procedure TCustomTestPrecompile.CheckRestoredProcScope(const Path: string;
   Orig, Rest: TPas2JSProcedureScope);
   Orig, Rest: TPas2JSProcedureScope);
 begin
 begin
@@ -405,6 +469,37 @@ begin
   CheckRestoredIdentifierScope(Path,Orig,Rest);
   CheckRestoredIdentifierScope(Path,Orig,Rest);
 end;
 end;
 
 
+procedure TCustomTestPrecompile.CheckRestoredPropertyScope(const Path: string;
+  Orig, Rest: TPasPropertyScope);
+begin
+  CheckRestoredReference(Path+'.AncestorProp',Orig.AncestorProp,Rest.AncestorProp);
+  CheckRestoredIdentifierScope(Path,Orig,Rest);
+end;
+
+procedure TCustomTestPrecompile.CheckRestoredResolvedReference(
+  const Path: string; Orig, Rest: TResolvedReference);
+var
+  C: TClass;
+begin
+  if Orig.Flags<>Rest.Flags then
+    Fail(Path+'.Flags');
+  if Orig.Access<>Rest.Access then
+    AssertEquals(Path+'.Access',PJUResolvedRefAccessNames[Orig.Access],PJUResolvedRefAccessNames[Rest.Access]);
+  if not CheckRestoredObject(Path+'.Context',Orig.Context,Rest.Context) then exit;
+  if Orig.Context<>nil then
+    begin
+    C:=Orig.Context.ClassType;
+    if C=TResolvedRefCtxConstructor then
+      CheckRestoredReference(Path+'.Context[TResolvedRefCtxConstructor].Typ',
+        TResolvedRefCtxConstructor(Orig.Context).Typ,
+        TResolvedRefCtxConstructor(Rest.Context).Typ);
+    end;
+  CheckRestoredScopeReference(Path+'.WithExprScope',Orig.WithExprScope,Rest.WithExprScope);
+  CheckRestoredReference(Path+'.Declaration',Orig.Declaration,Rest.Declaration);
+
+  CheckRestoredResolveData(Path,Orig,Rest);
+end;
+
 procedure TCustomTestPrecompile.CheckRestoredCustomData(const Path: string;
 procedure TCustomTestPrecompile.CheckRestoredCustomData(const Path: string;
   El: TPasElement; Orig, Rest: TObject);
   El: TPasElement; Orig, Rest: TObject);
 var
 var
@@ -413,16 +508,52 @@ begin
   if not CheckRestoredObject(Path,Orig,Rest) then exit;
   if not CheckRestoredObject(Path,Orig,Rest) then exit;
 
 
   C:=Orig.ClassType;
   C:=Orig.ClassType;
-  if C=TPasModuleScope then
+  if C=TResolvedReference then
+    CheckRestoredResolvedReference(Path+'[TResolvedReference]',TResolvedReference(Orig),TResolvedReference(Rest))
+  else if C=TPasModuleScope then
     CheckRestoredModuleScope(Path+'[TPasModuleScope]',TPasModuleScope(Orig),TPasModuleScope(Rest))
     CheckRestoredModuleScope(Path+'[TPasModuleScope]',TPasModuleScope(Orig),TPasModuleScope(Rest))
   else if C=TPasSectionScope then
   else if C=TPasSectionScope then
     CheckRestoredSectionScope(Path+'[TPasSectionScope]',TPasSectionScope(Orig),TPasSectionScope(Rest))
     CheckRestoredSectionScope(Path+'[TPasSectionScope]',TPasSectionScope(Orig),TPasSectionScope(Rest))
+  else if C=TPasEnumTypeScope then
+    CheckRestoredEnumTypeScope(Path+'[TPasEnumTypeScope]',TPasEnumTypeScope(Orig),TPasEnumTypeScope(Rest))
+  else if C=TPasRecordScope then
+    CheckRestoredRecordScope(Path+'[TPasRecordScope]',TPasRecordScope(Orig),TPasRecordScope(Rest))
+  else if C=TPas2JSClassScope then
+    CheckRestoredClassScope(Path+'[TPas2JSClassScope]',TPas2JSClassScope(Orig),TPas2JSClassScope(Rest))
   else if C=TPas2JSProcedureScope then
   else if C=TPas2JSProcedureScope then
     CheckRestoredProcScope(Path+'[TPas2JSProcedureScope]',TPas2JSProcedureScope(Orig),TPas2JSProcedureScope(Rest))
     CheckRestoredProcScope(Path+'[TPas2JSProcedureScope]',TPas2JSProcedureScope(Orig),TPas2JSProcedureScope(Rest))
+  else if C=TPasPropertyScope then
+    CheckRestoredPropertyScope(Path+'[TPasPropertyScope]',TPasPropertyScope(Orig),TPasPropertyScope(Rest))
   else
   else
     Fail(Path+': unknown CustomData "'+GetObjName(Orig)+'" El='+GetObjName(El));
     Fail(Path+': unknown CustomData "'+GetObjName(Orig)+'" El='+GetObjName(El));
 end;
 end;
 
 
+procedure TCustomTestPrecompile.CheckRestoredReference(const Path: string;
+  Orig, Rest: TPasElement);
+begin
+  if not CheckRestoredObject(Path,Orig,Rest) then exit;
+  AssertEquals(Path+': Name',Orig.Name,Rest.Name);
+
+  if Orig is TPasUnresolvedSymbolRef then
+    exit; // compiler types and procs are the same in every unit -> skip checking unit
+
+  CheckRestoredReference(Path+'.Parent',Orig.Parent,Rest.Parent);
+end;
+
+procedure TCustomTestPrecompile.CheckRestoredElOrRef(const Path: string; Orig,
+  OrigProp, Rest, RestProp: TPasElement);
+begin
+  if not CheckRestoredObject(Path,OrigProp,RestProp) then exit;
+  if Orig<>OrigProp.Parent then
+    begin
+    if Rest=RestProp.Parent then
+      Fail(Path+' Orig "'+GetObjName(OrigProp)+'" is reference Orig.Parent='+GetObjName(Orig)+', Rest "'+GetObjName(RestProp)+'" is insitu');
+    CheckRestoredReference(Path,OrigProp,RestProp);
+    end
+  else
+    CheckRestoredElement(Path,OrigProp,RestProp);
+end;
+
 procedure TCustomTestPrecompile.CheckRestoredElement(const Path: string; Orig,
 procedure TCustomTestPrecompile.CheckRestoredElement(const Path: string; Orig,
   Rest: TPasElement);
   Rest: TPasElement);
 var
 var
@@ -440,15 +571,7 @@ begin
     Fail(Path+': Hints');
     Fail(Path+': Hints');
   AssertEquals(Path+': HintMessage',Orig.HintMessage,Rest.HintMessage);
   AssertEquals(Path+': HintMessage',Orig.HintMessage,Rest.HintMessage);
 
 
-  if Orig.Parent=nil then
-    begin
-    if Rest.Parent<>nil then
-      Fail(Path+': Orig.Parent=nil Rest.Parent='+GetObjName(Rest.Parent));
-    end
-  else if Rest.Parent=nil then
-    Fail(Path+': Orig.Parent='+GetObjName(Orig.Parent)+' Rest.Parent=nil')
-  else if Orig.Parent.ClassType<>Rest.Parent.ClassType then
-    Fail(Path+': Orig.Parent='+GetObjName(Orig.Parent)+' Rest.Parent='+GetObjName(Rest.Parent));
+  CheckRestoredReference(Path+'.Parent',Orig.Parent,Rest.Parent);
 
 
   CheckRestoredCustomData(Path+'.CustomData',Rest,Orig.CustomData,Rest.CustomData);
   CheckRestoredCustomData(Path+'.CustomData',Rest,Orig.CustomData,Rest.CustomData);
 
 
@@ -568,6 +691,32 @@ begin
     end;
     end;
 end;
 end;
 
 
+procedure TCustomTestPrecompile.CheckRestoredElRefList(const Path: string;
+  OrigParent: TPasElement; Orig: TFPList; RestParent: TPasElement;
+  Rest: TFPList; AllowInSitu: boolean);
+var
+  OrigItem, RestItem: TObject;
+  i: Integer;
+  SubPath: String;
+begin
+  if not CheckRestoredObject(Path,Orig,Rest) then exit;
+  AssertEquals(Path+'.Count',Orig.Count,Rest.Count);
+  for i:=0 to Orig.Count-1 do
+    begin
+    SubPath:=Path+'['+IntToStr(i)+']';
+    OrigItem:=TObject(Orig[i]);
+    if not (OrigItem is TPasElement) then
+      Fail(SubPath+' Orig='+GetObjName(OrigItem));
+    RestItem:=TObject(Rest[i]);
+    if not (RestItem is TPasElement) then
+      Fail(SubPath+' Rest='+GetObjName(RestItem));
+    if AllowInSitu then
+      CheckRestoredElOrRef(SubPath,OrigParent,TPasElement(OrigItem),RestParent,TPasElement(RestItem))
+    else
+      CheckRestoredReference(SubPath,TPasElement(OrigItem),TPasElement(RestItem));
+    end;
+end;
+
 procedure TCustomTestPrecompile.CheckRestoredPasExpr(const Path: string; Orig,
 procedure TCustomTestPrecompile.CheckRestoredPasExpr(const Path: string; Orig,
   Rest: TPasExpr);
   Rest: TPasExpr);
 begin
 begin
@@ -656,27 +805,27 @@ end;
 procedure TCustomTestPrecompile.CheckRestoredAliasType(const Path: string;
 procedure TCustomTestPrecompile.CheckRestoredAliasType(const Path: string;
   Orig, Rest: TPasAliasType);
   Orig, Rest: TPasAliasType);
 begin
 begin
-  CheckRestoredElement(Path+'.DestType',Orig.DestType,Rest.DestType);
+  CheckRestoredElOrRef(Path+'.DestType',Orig,Orig.DestType,Rest,Rest.DestType);
   CheckRestoredElement(Path+'.Expr',Orig.Expr,Rest.Expr);
   CheckRestoredElement(Path+'.Expr',Orig.Expr,Rest.Expr);
 end;
 end;
 
 
 procedure TCustomTestPrecompile.CheckRestoredPointerType(const Path: string;
 procedure TCustomTestPrecompile.CheckRestoredPointerType(const Path: string;
   Orig, Rest: TPasPointerType);
   Orig, Rest: TPasPointerType);
 begin
 begin
-  CheckRestoredElement(Path+'.DestType',Orig.DestType,Rest.DestType);
+  CheckRestoredElOrRef(Path+'.DestType',Orig,Orig.DestType,Rest,Rest.DestType);
 end;
 end;
 
 
 procedure TCustomTestPrecompile.CheckRestoredSpecializedType(
 procedure TCustomTestPrecompile.CheckRestoredSpecializedType(
   const Path: string; Orig, Rest: TPasSpecializeType);
   const Path: string; Orig, Rest: TPasSpecializeType);
 begin
 begin
   CheckRestoredElementList(Path+'.Params',Orig.Params,Rest.Params);
   CheckRestoredElementList(Path+'.Params',Orig.Params,Rest.Params);
-  CheckRestoredElement(Path+'.DestType',Orig.DestType,Rest.DestType);
+  CheckRestoredElOrRef(Path+'.DestType',Orig,Orig.DestType,Rest,Rest.DestType);
 end;
 end;
 
 
 procedure TCustomTestPrecompile.CheckRestoredInlineSpecializedExpr(
 procedure TCustomTestPrecompile.CheckRestoredInlineSpecializedExpr(
   const Path: string; Orig, Rest: TInlineSpecializeExpr);
   const Path: string; Orig, Rest: TInlineSpecializeExpr);
 begin
 begin
-  CheckRestoredElement(Path+'.DestType',Orig.DestType,Rest.DestType);
+  CheckRestoredElOrRef(Path+'.DestType',Orig,Orig.DestType,Rest,Rest.DestType);
 end;
 end;
 
 
 procedure TCustomTestPrecompile.CheckRestoredRangeType(const Path: string;
 procedure TCustomTestPrecompile.CheckRestoredRangeType(const Path: string;
@@ -691,13 +840,13 @@ begin
   CheckRestoredPasExprArray(Path+'.Ranges',Orig.Ranges,Rest.Ranges);
   CheckRestoredPasExprArray(Path+'.Ranges',Orig.Ranges,Rest.Ranges);
   if Orig.PackMode<>Rest.PackMode then
   if Orig.PackMode<>Rest.PackMode then
     Fail(Path+'.PackMode Orig='+PJUPackModeNames[Orig.PackMode]+' Rest='+PJUPackModeNames[Rest.PackMode]);
     Fail(Path+'.PackMode Orig='+PJUPackModeNames[Orig.PackMode]+' Rest='+PJUPackModeNames[Rest.PackMode]);
-  CheckRestoredElement(Path+'.ElType',Orig.ElType,Rest.ElType);
+  CheckRestoredElOrRef(Path+'.ElType',Orig,Orig.ElType,Rest,Rest.ElType);
 end;
 end;
 
 
 procedure TCustomTestPrecompile.CheckRestoredFileType(const Path: string; Orig,
 procedure TCustomTestPrecompile.CheckRestoredFileType(const Path: string; Orig,
   Rest: TPasFileType);
   Rest: TPasFileType);
 begin
 begin
-  CheckRestoredElement(Path+'.ElType',Orig.ElType,Rest.ElType);
+  CheckRestoredElOrRef(Path+'.ElType',Orig,Orig.ElType,Rest,Rest.ElType);
 end;
 end;
 
 
 procedure TCustomTestPrecompile.CheckRestoredEnumValue(const Path: string;
 procedure TCustomTestPrecompile.CheckRestoredEnumValue(const Path: string;
@@ -715,7 +864,7 @@ end;
 procedure TCustomTestPrecompile.CheckRestoredSetType(const Path: string; Orig,
 procedure TCustomTestPrecompile.CheckRestoredSetType(const Path: string; Orig,
   Rest: TPasSetType);
   Rest: TPasSetType);
 begin
 begin
-  CheckRestoredElement(Path+'.EnumType',Orig.EnumType,Rest.EnumType);
+  CheckRestoredElOrRef(Path+'.EnumType',Orig,Orig.EnumType,Rest,Rest.EnumType);
   AssertEquals(Path+'.IsPacked',Orig.IsPacked,Rest.IsPacked);
   AssertEquals(Path+'.IsPacked',Orig.IsPacked,Rest.IsPacked);
 end;
 end;
 
 
@@ -732,7 +881,7 @@ begin
   if Orig.PackMode<>Rest.PackMode then
   if Orig.PackMode<>Rest.PackMode then
     Fail(Path+'.PackMode Orig='+PJUPackModeNames[Orig.PackMode]+' Rest='+PJUPackModeNames[Rest.PackMode]);
     Fail(Path+'.PackMode Orig='+PJUPackModeNames[Orig.PackMode]+' Rest='+PJUPackModeNames[Rest.PackMode]);
   CheckRestoredElementList(Path+'.Members',Orig.Members,Rest.Members);
   CheckRestoredElementList(Path+'.Members',Orig.Members,Rest.Members);
-  CheckRestoredElement(Path+'.VariantEl',Orig.VariantEl,Rest.VariantEl);
+  CheckRestoredElOrRef(Path+'.VariantEl',Orig,Orig.VariantEl,Rest,Rest.VariantEl);
   CheckRestoredElementList(Path+'.Variants',Orig.Variants,Rest.Variants);
   CheckRestoredElementList(Path+'.Variants',Orig.Variants,Rest.Variants);
   CheckRestoredElementList(Path+'.GenericTemplateTypes',Orig.GenericTemplateTypes,Rest.GenericTemplateTypes);
   CheckRestoredElementList(Path+'.GenericTemplateTypes',Orig.GenericTemplateTypes,Rest.GenericTemplateTypes);
 end;
 end;
@@ -744,15 +893,15 @@ begin
     Fail(Path+'.PackMode Orig='+PJUPackModeNames[Orig.PackMode]+' Rest='+PJUPackModeNames[Rest.PackMode]);
     Fail(Path+'.PackMode Orig='+PJUPackModeNames[Orig.PackMode]+' Rest='+PJUPackModeNames[Rest.PackMode]);
   if Orig.ObjKind<>Rest.ObjKind then
   if Orig.ObjKind<>Rest.ObjKind then
     Fail(Path+'.ObjKind Orig='+PJUObjKindNames[Orig.ObjKind]+' Rest='+PJUObjKindNames[Rest.ObjKind]);
     Fail(Path+'.ObjKind Orig='+PJUObjKindNames[Orig.ObjKind]+' Rest='+PJUObjKindNames[Rest.ObjKind]);
-  CheckRestoredElement(Path+'.AncestorType',Orig.AncestorType,Rest.AncestorType);
-  CheckRestoredElement(Path+'.HelperForType',Orig.HelperForType,Rest.HelperForType);
+  CheckRestoredReference(Path+'.AncestorType',Orig.AncestorType,Rest.AncestorType);
+  CheckRestoredReference(Path+'.HelperForType',Orig.HelperForType,Rest.HelperForType);
   AssertEquals(Path+'.IsForward',Orig.IsForward,Rest.IsForward);
   AssertEquals(Path+'.IsForward',Orig.IsForward,Rest.IsForward);
   AssertEquals(Path+'.IsExternal',Orig.IsExternal,Rest.IsExternal);
   AssertEquals(Path+'.IsExternal',Orig.IsExternal,Rest.IsExternal);
   // irrelevant: IsShortDefinition
   // irrelevant: IsShortDefinition
   CheckRestoredElement(Path+'.GUIDExpr',Orig.GUIDExpr,Rest.GUIDExpr);
   CheckRestoredElement(Path+'.GUIDExpr',Orig.GUIDExpr,Rest.GUIDExpr);
   CheckRestoredElementList(Path+'.Members',Orig.Members,Rest.Members);
   CheckRestoredElementList(Path+'.Members',Orig.Members,Rest.Members);
   AssertEquals(Path+'.Modifiers',Orig.Modifiers.Text,Rest.Modifiers.Text);
   AssertEquals(Path+'.Modifiers',Orig.Modifiers.Text,Rest.Modifiers.Text);
-  CheckRestoredElementList(Path+'.Interfaces',Orig.Interfaces,Rest.Interfaces);
+  CheckRestoredElRefList(Path+'.Interfaces',Orig,Orig.Interfaces,Rest,Rest.Interfaces,false);
   CheckRestoredElementList(Path+'.GenericTemplateTypes',Orig.GenericTemplateTypes,Rest.GenericTemplateTypes);
   CheckRestoredElementList(Path+'.GenericTemplateTypes',Orig.GenericTemplateTypes,Rest.GenericTemplateTypes);
   AssertEquals(Path+'.ExternalNameSpace',Orig.ExternalNameSpace,Rest.ExternalNameSpace);
   AssertEquals(Path+'.ExternalNameSpace',Orig.ExternalNameSpace,Rest.ExternalNameSpace);
   AssertEquals(Path+'.ExternalName',Orig.ExternalName,Rest.ExternalName);
   AssertEquals(Path+'.ExternalName',Orig.ExternalName,Rest.ExternalName);
@@ -763,7 +912,7 @@ procedure TCustomTestPrecompile.CheckRestoredArgument(const Path: string; Orig,
 begin
 begin
   if Orig.Access<>Rest.Access then
   if Orig.Access<>Rest.Access then
     Fail(Path+'.Access Orig='+PJUArgumentAccessNames[Orig.Access]+' Rest='+PJUArgumentAccessNames[Rest.Access]);
     Fail(Path+'.Access Orig='+PJUArgumentAccessNames[Orig.Access]+' Rest='+PJUArgumentAccessNames[Rest.Access]);
-  CheckRestoredElement(Path+'.ArgType',Orig.ArgType,Rest.ArgType);
+  CheckRestoredElOrRef(Path+'.ArgType',Orig,Orig.ArgType,Rest,Rest.ArgType);
   CheckRestoredElement(Path+'.ValueExpr',Orig.ValueExpr,Rest.ValueExpr);
   CheckRestoredElement(Path+'.ValueExpr',Orig.ValueExpr,Rest.ValueExpr);
 end;
 end;
 
 
@@ -780,7 +929,7 @@ end;
 procedure TCustomTestPrecompile.CheckRestoredResultElement(const Path: string;
 procedure TCustomTestPrecompile.CheckRestoredResultElement(const Path: string;
   Orig, Rest: TPasResultElement);
   Orig, Rest: TPasResultElement);
 begin
 begin
-  CheckRestoredElement(Path+'.ResultType',Orig.ResultType,Rest.ResultType);
+  CheckRestoredElOrRef(Path+'.ResultType',Orig,Orig.ResultType,Rest,Rest.ResultType);
 end;
 end;
 
 
 procedure TCustomTestPrecompile.CheckRestoredFunctionType(const Path: string;
 procedure TCustomTestPrecompile.CheckRestoredFunctionType(const Path: string;
@@ -799,7 +948,7 @@ end;
 procedure TCustomTestPrecompile.CheckRestoredVariable(const Path: string; Orig,
 procedure TCustomTestPrecompile.CheckRestoredVariable(const Path: string; Orig,
   Rest: TPasVariable);
   Rest: TPasVariable);
 begin
 begin
-  CheckRestoredElement(Path+'.VarType',Orig.VarType,Rest.VarType);
+  CheckRestoredElOrRef(Path+'.VarType',Orig,Orig.VarType,Rest,Rest.VarType);
   if Orig.VarModifiers<>Rest.VarModifiers then
   if Orig.VarModifiers<>Rest.VarModifiers then
     Fail(Path+'.VarModifiers');
     Fail(Path+'.VarModifiers');
   CheckRestoredElement(Path+'.LibraryName',Orig.LibraryName,Rest.LibraryName);
   CheckRestoredElement(Path+'.LibraryName',Orig.LibraryName,Rest.LibraryName);
@@ -866,18 +1015,6 @@ begin
   CheckRestoredProcedure(Path,Orig,Rest);
   CheckRestoredProcedure(Path,Orig,Rest);
 end;
 end;
 
 
-procedure TCustomTestPrecompile.CheckRestoredReference(const Path: string;
-  Orig, Rest: TPasElement);
-begin
-  if not CheckRestoredObject(Path,Orig,Rest) then exit;
-  AssertEquals(Path+': Name',Orig.Name,Rest.Name);
-
-  if Orig is TPasUnresolvedSymbolRef then
-    exit; // compiler types and procs are the same in every unit -> skip checking unit
-
-  CheckRestoredReference(Path+'.Parent',Orig.Parent,Rest.Parent);
-end;
-
 { TTestPrecompile }
 { TTestPrecompile }
 
 
 procedure TTestPrecompile.Test_Base256VLQ;
 procedure TTestPrecompile.Test_Base256VLQ;

+ 51 - 0
packages/pastojs/tests/tcmodules.pas

@@ -378,6 +378,7 @@ type
     Procedure TestClass_PropertyOfTypeArray;
     Procedure TestClass_PropertyOfTypeArray;
     Procedure TestClass_PropertyDefault;
     Procedure TestClass_PropertyDefault;
     Procedure TestClass_PropertyOverride;
     Procedure TestClass_PropertyOverride;
+    Procedure TestClass_PropertyIncVisibility;
     Procedure TestClass_Assigned;
     Procedure TestClass_Assigned;
     Procedure TestClass_WithClassDoCreate;
     Procedure TestClass_WithClassDoCreate;
     Procedure TestClass_WithClassInstDoProperty;
     Procedure TestClass_WithClassInstDoProperty;
@@ -8423,6 +8424,56 @@ begin
     '']));
     '']));
 end;
 end;
 
 
+procedure TTestModule.TestClass_PropertyIncVisibility;
+begin
+  AddModuleWithIntfImplSrc('unit1.pp',
+    LinesToStr([
+    'type',
+    '  TNumber = longint;',
+    '  TInteger = longint;',
+    '  TObject = class',
+    '  private',
+    '    function GetItems(Index: TNumber): TInteger; virtual; abstract;',
+    '    procedure SetItems(Index: TInteger; Value: TNumber); virtual; abstract;',
+    '  protected',
+    '    property Items[Index: TNumber]: longint read GetItems write SetItems;',
+    '  end;']),
+    LinesToStr([
+    '']));
+
+  StartProgram(true);
+  Add([
+  'uses unit1;',
+  'type',
+  '  TBird = class',
+  '  public',
+  '    property Items;',
+  '  end;',
+  'procedure DoIt(i: TInteger);',
+  'begin',
+  'end;',
+  'var b: TBird;',
+  'begin',
+  '  b.Items[1]:=2;',
+  '  b.Items[3]:=b.Items[4];',
+  '  DoIt(b.Items[5]);',
+  '']);
+  ConvertProgram;
+  CheckSource('TestClass_PropertyIncVisibility',
+    LinesToStr([ // statements
+    'rtl.createClass($mod, "TBird", pas.unit1.TObject, function () {',
+    '});',
+    'this.DoIt = function (i) {',
+    '};',
+    'this.b = null;'
+    ]),
+    LinesToStr([ // $mod.$main
+    '$mod.b.SetItems(1, 2);',
+    '$mod.b.SetItems(3, $mod.b.GetItems(4));',
+    '$mod.DoIt($mod.b.GetItems(5));'
+    ]));
+end;
+
 procedure TTestModule.TestClass_Assigned;
 procedure TTestModule.TestClass_Assigned;
 begin
 begin
   StartProgram(false);
   StartProgram(false);