Forráskód Böngészése

* patch by Ondrej Pokorny: The nodefault is now inherited from parent class, resolves #33563

git-svn-id: trunk@39356 -
florian 7 éve
szülő
commit
eb61923762
3 módosított fájl, 179 hozzáadás és 1 törlés
  1. 1 0
      .gitattributes
  2. 1 1
      compiler/pdecvar.pas
  3. 177 0
      tests/webtbs/tw33563.pp

+ 1 - 0
.gitattributes

@@ -16177,6 +16177,7 @@ tests/webtbs/tw3353.pp svneol=native#text/plain
 tests/webtbs/tw33542.pp svneol=native#text/pascal
 tests/webtbs/tw33548.pp svneol=native#text/plain
 tests/webtbs/tw3356.pp svneol=native#text/plain
+tests/webtbs/tw33563.pp svneol=native#text/pascal
 tests/webtbs/tw3360.pp svneol=native#text/plain
 tests/webtbs/tw33635.pp svneol=native#text/pascal
 tests/webtbs/tw3364.pp svneol=native#text/plain

+ 1 - 1
compiler/pdecvar.pas

@@ -666,7 +666,7 @@ implementation
                   end;
               end;
            end;
-         if has_implicit_default(p) then
+         if has_implicit_default(p) and not assigned(p.overriddenpropsym) then
            begin
               p.default:=0;
            end;

+ 177 - 0
tests/webtbs/tw33563.pp

@@ -0,0 +1,177 @@
+program EmptyRealWriter;
+
+{$mode objfpc}{$h+}
+
+uses
+  SysUtils, Classes, Math;
+
+type
+  TMyComp = class(TComponent)
+  public const
+    cDefS = Pi;
+  private
+    fS: Double;
+    fT: Double;
+    fU: Double;
+    fSn: Double;
+    fTn: Double;
+    fUn: Double;
+    fSdef: Double;
+    function SStored: Boolean;
+    function SnStored: Boolean;
+    function SdefStored: Boolean;
+  public
+    constructor Create(AOwner: TComponent); override;
+  published
+    property S: Double read fS write fS stored SStored nodefault;
+    property T: Double read fT write fT nodefault;    // stored implicitely True
+    property U: Double read fU write fU;              // stored implicitely True, default=0
+    property Sn: Double read fSn write fSn stored SnStored nodefault;
+    property Tn: Double read fTn write fTn nodefault; // stored implicitely True
+    property Un: Double read fUn write fUn;           // stored implicitely True, default=0
+    property Sdef: Double read fSdef write fSdef stored SdefStored nodefault;
+  end;
+  TMyCompClass = class of TMyComp;
+
+  TMyComp2 = class(TMyComp)
+  published
+    property S;
+    property T;
+    property U;
+    property Sn;
+    property Tn;
+    property Un;
+    property Sdef;
+  end;
+
+{ TMyComp }
+
+constructor TMyComp.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+
+  fS := cDefS;
+  fSn := cDefS;
+  fSdef := cDefS;
+end;
+
+function TMyComp.SdefStored: Boolean;
+begin
+  Result := not SameValue(fSdef, cDefS);
+end;
+
+function TMyComp.SnStored: Boolean;
+begin
+  Result := not SameValue(fSn, cDefS);
+end;
+
+function TMyComp.SStored: Boolean;
+begin
+  Result := not SameValue(fS, cDefS);
+end;
+
+procedure CheckStringRead(const aReader: TBinaryObjectReader; const aExpectedValue: string);
+var
+  S: string;
+begin
+  S := aReader.ReadStr;
+  if S<>aExpectedValue then
+    raise Exception.CreateFmt('Reader error [''%s'' <> ''%s'']', [S, aExpectedValue]);
+end;
+
+procedure CheckFloatRead(const aReader: TBinaryObjectReader; const aExpectedValue: Double);
+var
+  F: Double;
+begin
+  if aReader.ReadInt8 <> Ord(vaExtended) then
+    raise Exception.Create('Reader error: wrong property');
+  F := aReader.ReadFloat;
+  if not SameValue(F, aExpectedValue) then
+    raise Exception.CreateFmt('Reader error [''%f'' <> ''%f'']', [F, aExpectedValue]);
+end;
+
+var
+  xStream: TStream;
+  xWriter: TWriter;
+  Cl: TMyCompClass;
+  C: TMyComp;
+  xReader: TReader;
+  xObjReader: TBinaryObjectReader;
+  I: Integer;
+begin
+  for I := 0 to 1 do
+  begin
+    try
+      case I of
+        0: Cl := TMyComp;
+        1: Cl := TMyComp2;
+      end;
+      xStream := TMemoryStream.Create;
+      C := Cl.Create(nil);
+      C.S := 0;
+      C.T := 0;
+      C.U := 0;
+      C.Sn := 5;
+      C.Tn := 5;
+      C.Un := 5;
+      //keep SDef to default value -> won't be streamed
+      xWriter := TWriter.Create(xStream, 1024);
+      xWriter.WriteComponent(C);
+      C.Free;
+      xWriter.Free;
+      xStream.Position := 0;
+
+      xObjReader := TBinaryObjectReader.Create(xStream, 1);
+      CheckStringRead(xObjReader, Cl.ClassName);
+      CheckStringRead(xObjReader, '');
+      CheckStringRead(xObjReader, 'S');
+      CheckFloatRead(xObjReader, 0);
+      CheckStringRead(xObjReader, 'T');
+      CheckFloatRead(xObjReader, 0);
+      CheckStringRead(xObjReader, 'Sn');
+      CheckFloatRead(xObjReader, 5);
+      CheckStringRead(xObjReader, 'Tn');
+      CheckFloatRead(xObjReader, 5);
+      CheckStringRead(xObjReader, 'Un');
+      CheckFloatRead(xObjReader, 5);
+      if xObjReader.ReadInt16<>0 then
+        raise Exception.Create('Too many properties were streamed');
+      if xStream.Position <> xStream.Size then
+        raise Exception.Create('Too many properties were streamed.');
+      xObjReader.Free;
+      xStream.Position := 0;
+
+      C := Cl.Create(nil);
+      xReader := TReader.Create(xStream, 1024);
+      xReader.BeginReferences;
+      xReader.ReadComponent(C);
+      xReader.EndReferences;
+      if not SameValue(C.S, 0) then
+        raise Exception.Create('S invalid.');
+      if not SameValue(C.T, 0) then
+        raise Exception.Create('T invalid.');
+      if not SameValue(C.U, 0) then
+        raise Exception.Create('U invalid.');
+      if not SameValue(C.Sn, 5) then
+        raise Exception.Create('Sn invalid.');
+      if not SameValue(C.Tn, 5) then
+        raise Exception.Create('Tn invalid.');
+      if not SameValue(C.Un, 5) then
+        raise Exception.Create('Un invalid.');
+      if not SameValue(C.Sdef, TMyComp.cDefS) then
+        raise Exception.Create('Sdef invalid.');
+      C.Free;
+      xReader.Free;
+      xStream.Free;
+    except
+      on E: Exception do
+      begin
+        Writeln('Class: ', Cl.ClassName);
+        Writeln('Error: ', E.ClassName);
+        WriteLn(E.Message);
+        Halt(1);
+      end;
+    end;
+  end;
+end.
+