From dc5c4b535c9c112c9172b73e4f937de6dba03e4e Mon Sep 17 00:00:00 2001 From: juha Date: Wed, 17 Aug 2016 10:40:39 +0000 Subject: [PATCH] Packager: Support dotted package names. Issue #30467. git-svn-id: trunk@52813 - --- components/ideintf/ideutils.pas | 40 ++++++++++++++++++++++++++++++ components/ideintf/packageintf.pas | 2 +- components/ideintf/propedits.pp | 21 +++------------- packager/packagedefs.pas | 2 +- packager/packageeditor.pas | 11 ++++---- 5 files changed, 51 insertions(+), 25 deletions(-) diff --git a/components/ideintf/ideutils.pas b/components/ideintf/ideutils.pas index 9ea53ace6f..87ed18d542 100644 --- a/components/ideintf/ideutils.pas +++ b/components/ideintf/ideutils.pas @@ -26,6 +26,8 @@ type function IndexInStringList(List: TStrings; Cmp: TCmpStrType; s: string): integer; procedure SetComboBoxText(AComboBox: TComboBox; const AText: String; Cmp: TCmpStrType; MaxCount: integer = 1000); +function LazIsValidIdent(const Ident: string; AllowDots: Boolean = False; + StrictDots: Boolean = False): Boolean; implementation @@ -62,5 +64,43 @@ begin AComboBox.Text := AText; end; +function LazIsValidIdent(const Ident: string; AllowDots: Boolean = False; + StrictDots: Boolean = False): Boolean; +// This is a copy of IsValidIdent from FPC 3.1. +// ToDo: Switch to using IsValidIdent from FPC 3.2 when it is the minimum requirement. +const + Alpha = ['A'..'Z', 'a'..'z', '_']; + AlphaNum = Alpha + ['0'..'9']; + Dot = '.'; +var + First: Boolean; + I, Len: Integer; +begin + Len := Length(Ident); + if Len < 1 then + Exit(False); + First := True; + for I := 1 to Len do + begin + if First then + begin + Result := Ident[I] in Alpha; + First := False; + end + else if AllowDots and (Ident[I] = Dot) then + begin + if StrictDots then + begin + Result := I < Len; + First := True; + end; + end + else + Result := Ident[I] in AlphaNum; + if not Result then + Break; + end; +end; + end. diff --git a/components/ideintf/packageintf.pas b/components/ideintf/packageintf.pas index 344804f1f7..2ab5fb018a 100644 --- a/components/ideintf/packageintf.pas +++ b/components/ideintf/packageintf.pas @@ -694,7 +694,7 @@ end; procedure TLazPackageID.SetName(const NewName: TComponentName); begin if Name=NewName then exit; - inherited SetName(NewName); + ChangeName(NewName); UpdateIDAsString; end; diff --git a/components/ideintf/propedits.pp b/components/ideintf/propedits.pp index 6ec2820fc0..2432c39f69 100644 --- a/components/ideintf/propedits.pp +++ b/components/ideintf/propedits.pp @@ -33,7 +33,7 @@ uses // LazUtils FileUtil, FPCAdds, // for StrToQWord in older fpc versions // IdeIntf - ObjInspStrConsts, PropEditUtils, + ObjInspStrConsts, PropEditUtils, IDEUtils, // Forms with .lfm files FrmSelectProps, StringsPropEditDlg, KeyValPropEditDlg, CollectionPropEditForm, FileFilterPropEditor, IDEWindowIntf; @@ -4321,22 +4321,6 @@ begin Result := True; end; -function IsValidPropName(const PropName: string): boolean; -var - i, len: integer; -begin - result := false; - len := length(PropName); - if len <> 0 then begin - result := PropName[1] in ['A'..'Z', 'a'..'z', '_']; - i := 1; - while (result) and (i < len) do begin - i := i + 1; - result := result and (PropName[i] in ['A'..'Z', 'a'..'z', '0'..'9', '_', '.']); - end ; - end ; -end ; - procedure TMethodPropertyEditor.Edit; { If the method does not exist in current lookuproot: create it Then jump to the source. @@ -4349,7 +4333,8 @@ var begin NewMethodName := GetValue; //DebugLn('### TMethodPropertyEditor.Edit A OldValue=',NewMethodName); - if not IsValidPropName(NewMethodName) or PropertyHook.MethodFromAncestor(GetMethodValue) then + if not LazIsValidIdent(NewMethodName, True, True) + or PropertyHook.MethodFromAncestor(GetMethodValue) then begin // the current method is from the ancestor // -> add an override with the default name diff --git a/packager/packagedefs.pas b/packager/packagedefs.pas index 19dc3658d6..e4b48c43b6 100644 --- a/packager/packagedefs.pas +++ b/packager/packagedefs.pas @@ -920,7 +920,7 @@ end; function IsValidPkgName(APkgName: String): Boolean; begin - Result := IsValidIdent(APkgName); + Result := IsDottedIdentifier(APkgName); end; function PkgFileTypeIdentToType(const s: string): TPkgFileType; diff --git a/packager/packageeditor.pas b/packager/packageeditor.pas index e0e96b040b..623cac1450 100644 --- a/packager/packageeditor.pas +++ b/packager/packageeditor.pas @@ -1837,8 +1837,10 @@ end; procedure TPackageEditorForm.SetLazPackage(const AValue: TLazPackage); begin - if (FLazPackage=AValue) and - not(Assigned(AValue) and (Name<>PackageEditorWindowPrefix+AValue.Name))//force editor name change when package name changed! + //force editor name change when package name changed! + if (FLazPackage=Nil) + and ( (AValue=Nil) or (Name=PackageEditorWindowPrefix + +StringReplace(AValue.Name,'.','_',[rfReplaceAll])) ) then exit; if FLazPackage<>nil then @@ -1854,9 +1856,8 @@ begin end; EnvironmentOptions.LastOpenPackages.Add(FLazPackage.Filename); MainIDE.SaveEnvironment; - Name:=PackageEditorWindowPrefix+LazPackage.Name; FLazPackage.Editor:=Self; - // update components + // set Name and update components. UpdateAll(true); end; @@ -2036,7 +2037,7 @@ procedure TPackageEditorForm.UpdateAll(Immediately: boolean); begin if csDestroying in ComponentState then exit; if LazPackage=nil then exit; - Name:=PackageEditorWindowPrefix+LazPackage.Name; + Name:=PackageEditorWindowPrefix + StringReplace(LazPackage.Name,'.','_',[rfReplaceAll]); if fForcedFlags<>[] then fFlags:=fFlags+fForcedFlags // Flags forcing a partial update else