diff --git a/components/jitclasses/jitclass.pas b/components/jitclasses/jitclass.pas index 87783d013c..151c0eb335 100644 --- a/components/jitclasses/jitclass.pas +++ b/components/jitclasses/jitclass.pas @@ -221,7 +221,9 @@ type FJitPVmt: PVmt; FRefCountedJitPVmt: TRefCountedJitClassReference; FAncestorClass: TClass; + FAncestorClassName: String; FAncestorJitClass: TJitClassCreator; + FAncestorJitType: TJitTypeClassBase; FClassName: String; FTypeLibrary: TJitTypeLibrary; @@ -234,7 +236,6 @@ type procedure DoTypeLibFreed(Sender: TObject); procedure DoAnchesterJitClassFreed(Sender: TObject); - function GetJitClass: TClass; procedure SetClassName(AValue: String); procedure SetClassUnit(AValue: String); procedure SetTypeLibrary(AValue: TJitTypeLibrary); @@ -244,6 +245,7 @@ type class procedure FreeJitClass(AJitPVmt: PVmt); function GetLockReferenceObj: TRefCountedJitReference; override; function GetTypeInfo: PTypeInfo; override; + function GetJitClass: TClass; override; procedure CreateJitClass; procedure CreateJitClassPreCheck; @@ -257,8 +259,10 @@ type procedure CreateJitPropsPrepare; procedure CreateJitPropsFinish; public - constructor Create(AnAncestorClass: TClass; AClassName: String; AClassUnit: String); - constructor Create(AnAncestorJitClass: TJitClassCreator; AClassName: String; AClassUnit: String); + constructor Create(AnAncestorClass: TClass; AClassName: String; AClassUnit: String; ATypeLibrary: TJitTypeLibrary = nil); + constructor Create(AnAncestorClassName, AClassName: String; AClassUnit: String; ATypeLibrary: TJitTypeLibrary = nil); + constructor Create(AnAncestorJitClass: TJitClassCreator; AClassName: String; AClassUnit: String; ATypeLibrary: TJitTypeLibrary = nil); + constructor Create(AnAncestorJitType: TJitType; AClassName: String; AClassUnit: String; ATypeLibrary: TJitTypeLibrary = nil); destructor Destroy; override; (* UpdateJitClass @@ -862,7 +866,7 @@ begin NewDefault:= ''; NewNoDefault := False; NewIsStored := True; - tk := Parser.CurrentKind; + tk := Parser.Next; if tk = ptIdent then begin // stopped at read or write while tk in [ptIdent, ptDot] do begin if (tk = ptIdent) then begin @@ -1125,7 +1129,23 @@ end; procedure TJitClassCreator.CreateJitClass; var HasJitAnchestor: Boolean; + at: TJitType; begin + if (FAncestorClass = nil) and (FAncestorJitClass = nil) then begin + if (FAncestorJitType = nil) and (FAncestorClassName <> '') and (FTypeLibrary <> nil) then begin + at := FTypeLibrary.FindType(FAncestorClassName, FClassUnit); + if not (at is TJitTypeClassBase) then + raise Exception.Create('Incorrect type for anchestor'); + FAncestorJitType := TJitTypeJitClass(at); + end; + + if FAncestorJitType <> nil then begin; + if (FAncestorJitType is TJitTypeJitClass) then + FAncestorJitClass := TJitClassCreator(TJitTypeJitClass(FAncestorJitType).JitClassCreator) + else + FAncestorClass := FAncestorJitType.JitClass; + end; + end; CreateJitClassPreCheck; FFlags := FFlags - [ccfModifiedMethods, ccfModifiedProps, ccfModifiedClassName]; @@ -1460,7 +1480,7 @@ begin end; constructor TJitClassCreator.Create(AnAncestorClass: TClass; - AClassName: String; AClassUnit: String); + AClassName: String; AClassUnit: String; ATypeLibrary: TJitTypeLibrary); begin FJitPVmt := nil; FJitMethods := TJitMethodList.Create(Self); @@ -1471,17 +1491,34 @@ begin FAncestorClass := AnAncestorClass; FClassName := AClassName; FClassUnit := AClassUnit; + TypeLibrary := ATypeLibrary; +end; + +constructor TJitClassCreator.Create(AnAncestorClassName, AClassName: String; + AClassUnit: String; ATypeLibrary: TJitTypeLibrary); +begin + Create(TClass(nil), AClassName, AClassUnit, ATypeLibrary); + FAncestorClassName := AnAncestorClassName; end; constructor TJitClassCreator.Create(AnAncestorJitClass: TJitClassCreator; - AClassName: String; AClassUnit: String); + AClassName: String; AClassUnit: String; ATypeLibrary: TJitTypeLibrary); begin - Create(TClass(nil), AClassName, AClassUnit); + Create(TClass(nil), AClassName, AClassUnit, ATypeLibrary); FAncestorJitClass := AnAncestorJitClass; if FAncestorJitClass <> nil then FAncestorJitClass.AddFreeNotification(@DoAnchesterJitClassFreed); end; +constructor TJitClassCreator.Create(AnAncestorJitType: TJitType; + AClassName: String; AClassUnit: String; ATypeLibrary: TJitTypeLibrary); +begin + if not (AnAncestorJitType is TJitTypeClassBase) then + raise Exception.Create('Incorrect type for anchestor'); + Create(TClass(nil), AClassName, AClassUnit, ATypeLibrary); + FAncestorJitType := TJitTypeClassBase(AnAncestorJitType); +end; + destructor TJitClassCreator.Destroy; begin inherited Destroy; diff --git a/components/jitclasses/jittypes.pas b/components/jitclasses/jittypes.pas index 79241681b0..2535c836c6 100644 --- a/components/jitclasses/jittypes.pas +++ b/components/jitclasses/jittypes.pas @@ -163,6 +163,7 @@ type protected FClassUnit: String; function GetTypeInfo: PTypeInfo; virtual; abstract; + function GetJitClass: TClass; virtual; abstract; public property TypeInfo: PTypeInfo read GetTypeInfo; property ClassUnit: String read FClassUnit; // write SetClassUnit; @@ -304,21 +305,29 @@ type end; + TJitTypeClassBase = class abstract (TJitType) + protected + function GetJitClass: TClass; virtual; abstract; + public + property JitClass: TClass read GetJitClass; + end; + { TJitTypeClass } - TJitTypeClass = class(TJitType) + TJitTypeClass = class(TJitTypeClassBase) private FClass: TClass; protected function GetTypeInfo: PTypeInfo; override; + function GetJitClass: TClass; override; public constructor Create(ATypeName: String; AClass: TClass; ATypeLibrary: TJitTypeLibrary = nil); end; { TJitTypeJitClass } - TJitTypeJitClass = class(TJitType) + TJitTypeJitClass = class(TJitTypeClassBase) private FJitClassCreator: TJitClassCreatorBase; FOwnJitCreator: Boolean; @@ -326,6 +335,7 @@ type protected function GetTypeInfo: PTypeInfo; override; + function GetJitClass: TClass; override; function GetLockReferenceInc: TRefCountedJitReference; override; function IsConstTypeInfo: Boolean; override; public @@ -333,6 +343,7 @@ type ATypeLibrary: TJitTypeLibrary = nil; ATakeOwnerShip: Boolean = False); destructor Destroy; override; + property JitClassCreator: TJitClassCreatorBase read FJitClassCreator; property OwnJitCreator: Boolean read FOwnJitCreator write FOwnJitCreator; end; @@ -457,6 +468,7 @@ end; constructor JitTypeParserException.Create(APos: Integer; const AToken, msg: string); begin + inherited Create(msg); FErrorPos := APos; FErrorToken := AToken; end; @@ -2182,6 +2194,11 @@ begin Result := FClass.ClassInfo; end; +function TJitTypeClass.GetJitClass: TClass; +begin + Result := FClass; +end; + constructor TJitTypeClass.Create(ATypeName: String; AClass: TClass; ATypeLibrary: TJitTypeLibrary); begin @@ -2204,6 +2221,14 @@ begin Result := nil; end; +function TJitTypeJitClass.GetJitClass: TClass; +begin + if FJitClassCreator <> nil then + Result := FJitClassCreator.GetJitClass + else + Result := nil; +end; + function TJitTypeJitClass.GetLockReferenceInc: TRefCountedJitReference; begin if FJitClassCreator <> nil then diff --git a/components/jitclasses/test/JitClassesTest.lpi b/components/jitclasses/test/JitClassesTest.lpi index 3d5f5075e3..5b717c1e5f 100644 --- a/components/jitclasses/test/JitClassesTest.lpi +++ b/components/jitclasses/test/JitClassesTest.lpi @@ -8,7 +8,6 @@