From ba310dcf48e978f04ef9ff61770c726761d7ec59 Mon Sep 17 00:00:00 2001 From: ondrej Date: Tue, 10 Nov 2015 10:38:58 +0000 Subject: [PATCH] IDE, CodeTools: improved character case recognition for units and namespaces. git-svn-id: trunk@50268 - --- components/codetools/basiccodetools.pas | 20 ++-- components/codetools/identcompletiontool.pas | 81 ++++++++++----- ide/sourceeditprocs.pas | 102 ++++++++++++------- 3 files changed, 130 insertions(+), 73 deletions(-) diff --git a/components/codetools/basiccodetools.pas b/components/codetools/basiccodetools.pas index a8e39dc0b0..d6b884f3b7 100644 --- a/components/codetools/basiccodetools.pas +++ b/components/codetools/basiccodetools.pas @@ -237,12 +237,12 @@ type TNameSpaceInfo = class private - FFilename: string; + FUnitName: string; FNamespace: string; FIdentifierStartInUnitName: Integer; public - constructor Create(const TheNamespace, TheFilename: string; TheIdentifierStartInUnitName: Integer); - property Filename: string read FFilename; + constructor Create(const TheNamespace, TheUnitName: string; TheIdentifierStartInUnitName: Integer); + property UnitName: string read FUnitName; property Namespace: string read FNamespace; property IdentifierStartInUnitName: Integer read FIdentifierStartInUnitName; end; @@ -260,7 +260,7 @@ procedure AddToTreeOfUnitFiles(var TreeOfUnitFiles: TAVLTree; const Filename, Unitname: string; KeepDoubles: boolean); procedure AddToTreeOfNamespaces(var TreeOfNameSpaces: TAVLTree; - const FileName, UnitName, ParentNameSpacePath: string; + const UnitName, ParentNameSpacePath: string; KeepDoubles: boolean); function CompareUnitFileInfos(Data1, Data2: Pointer): integer; function CompareNameSpaceInfos(Data1, Data2: Pointer): integer; @@ -5703,7 +5703,7 @@ begin AddToTreeOfUnitFiles(TreeOfUnitFiles,FileName,UnitName, KeepDoubles); if NameSpaceFits then - AddToTreeOfNamespaces(TreeOfNamespaces,FileName,UnitName,NameSpacePath, + AddToTreeOfNamespaces(TreeOfNamespaces,UnitName,NameSpacePath, KeepDoubles) end; @@ -5903,8 +5903,8 @@ begin TreeOfUnitFiles.Add(NewItem); end; -procedure AddToTreeOfNamespaces(var TreeOfNameSpaces: TAVLTree; const FileName, - UnitName, ParentNameSpacePath: string; KeepDoubles: boolean); +procedure AddToTreeOfNamespaces(var TreeOfNameSpaces: TAVLTree; const UnitName, + ParentNameSpacePath: string; KeepDoubles: boolean); var AnNameSpace: String; NewItem: TNameSpaceInfo; @@ -5927,7 +5927,7 @@ begin // add if TreeOfNameSpaces=nil then TreeOfNameSpaces:=TAVLTree.Create(@CompareNameSpaceInfos); - NewItem:=TNameSpaceInfo.Create(AnNameSpace,FileName,Length(ParentNameSpacePath)+1); + NewItem:=TNameSpaceInfo.Create(AnNameSpace,UnitName,Length(ParentNameSpacePath)+1); TreeOfNameSpaces.Add(NewItem); end; @@ -6089,11 +6089,11 @@ end; { TNameSpaceInfo } -constructor TNameSpaceInfo.Create(const TheNamespace, TheFilename: string; +constructor TNameSpaceInfo.Create(const TheNamespace, TheUnitName: string; TheIdentifierStartInUnitName: Integer); begin FNamespace:=TheNamespace; - FFilename:=TheFilename; + FUnitName:=TheUnitName; FIdentifierStartInUnitName:=TheIdentifierStartInUnitName; end; diff --git a/components/codetools/identcompletiontool.pas b/components/codetools/identcompletiontool.pas index 6b39e222b3..f5af2c22d8 100644 --- a/components/codetools/identcompletiontool.pas +++ b/components/codetools/identcompletiontool.pas @@ -113,6 +113,8 @@ type function CalcMemSize: PtrUInt; end; + TIdentifierList = class; + { TIdentifierListItem } TIdentifierListItem = class @@ -142,6 +144,7 @@ type Flags: TIdentListItemFlags; BaseExprType: TExpressionType; function AsString: string; + procedure BeautifyIdentifier({%H-}IdentList: TIdentifierList); virtual; function GetDesc: TCodeTreeNodeDesc; constructor Create(NewCompatibility: TIdentifierCompatibility; NewHasChilds: boolean; NewHistoryIndex: integer; @@ -176,13 +179,23 @@ type property ResultType: string read FResultType write SetResultType; property Node: TCodeTreeNode read GetNode write SetNode; end; + TIdentifierListItemClass = class of TIdentifierListItem; TUnitNameSpaceIdentifierListItem = class(TIdentifierListItem) public - UnitFileName: string; + FileUnitName: string; IdentifierStartInUnitName: Integer; + + constructor Create(NewCompatibility: TIdentifierCompatibility; + NewHasChilds: boolean; NewHistoryIndex: integer; + NewIdentifier: PChar; NewLevel: integer; + NewNode: TCodeTreeNode; NewTool: TFindDeclarationTool; + NewDefaultDesc: TCodeTreeNodeDesc; + NewFileUnitName: PChar; + NewIdentifierStartInUnitName: Integer); function CalcMemSize: PtrUInt; override; end; + TUnitNameSpaceIdentifierListItemClass = class of TUnitNameSpaceIdentifierListItem; TIdentifierListFlag = ( ilfFilteredListNeedsUpdate, @@ -427,6 +440,10 @@ type function dbgs(Flag: TIdentifierListContextFlag): string; overload; function dbgs(Flags: TIdentifierListContextFlags): string; overload; +var + CIdentifierListItem: TIdentifierListItemClass = TIdentifierListItem; + CUnitNameSpaceIdentifierListItem: TUnitNameSpaceIdentifierListItemClass = TUnitNameSpaceIdentifierListItem; + implementation const @@ -515,10 +532,23 @@ end; { TUnitNameSpaceIdentifierListItem } +constructor TUnitNameSpaceIdentifierListItem.Create( + NewCompatibility: TIdentifierCompatibility; NewHasChilds: boolean; + NewHistoryIndex: integer; NewIdentifier: PChar; NewLevel: integer; + NewNode: TCodeTreeNode; NewTool: TFindDeclarationTool; + NewDefaultDesc: TCodeTreeNodeDesc; NewFileUnitName: PChar; + NewIdentifierStartInUnitName: Integer); +begin + inherited Create(NewCompatibility, NewHasChilds, NewHistoryIndex, + NewIdentifier, NewLevel, NewNode, NewTool, NewDefaultDesc); + FileUnitName := NewFileUnitName; + IdentifierStartInUnitName := NewIdentifierStartInUnitName; +end; + function TUnitNameSpaceIdentifierListItem.CalcMemSize: PtrUInt; begin Result := inherited CalcMemSize - +MemSizeString(UnitFileName); + +MemSizeString(FileUnitName); end; { TIdentifierList } @@ -934,7 +964,7 @@ begin //DebugLn(['AddCompilerProcedure ',AProcName,' ',ilcfStartOfStatement in CurrentIdentifierList.ContextFlags]); if (ilcfDontAllowProcedures in CurrentIdentifierList.ContextFlags) then exit; - NewItem:=TIdentifierListItem.Create( + NewItem:=CIdentifierListItem.Create( icompUnknown, false, CompilerFuncHistoryIndex, @@ -953,7 +983,7 @@ procedure TIdentCompletionTool.AddKeyWord(aKeyWord: string); var NewItem: TIdentifierListItem; begin - NewItem:=TIdentifierListItem.Create( + NewItem:=CIdentifierListItem.Create( icompExact,false,0, CurrentIdentifierList.CreateIdentifier(aKeyWord), 1000,nil,nil,ctnNone); @@ -966,7 +996,7 @@ procedure TIdentCompletionTool.AddCompilerFunction(const AProcName, AParameterLi var NewItem: TIdentifierListItem; begin - NewItem:=TIdentifierListItem.Create( + NewItem:=CIdentifierListItem.Create( icompUnknown, false, CompilerFuncHistoryIndex, @@ -987,7 +1017,7 @@ procedure TIdentCompletionTool.AddBaseType(const BaseName: PChar); var NewItem: TIdentifierListItem; begin - NewItem:=TIdentifierListItem.Create( + NewItem:=CIdentifierListItem.Create( icompUnknown, false, CompilerFuncHistoryIndex, @@ -1003,7 +1033,7 @@ procedure TIdentCompletionTool.AddBaseConstant(const BaseName: PChar); var NewItem: TIdentifierListItem; begin - NewItem:=TIdentifierListItem.Create( + NewItem:=CIdentifierListItem.Create( icompUnknown, false, CompilerFuncHistoryIndex, @@ -1257,7 +1287,7 @@ begin end; if Ident=nil then exit; - NewItem:=TIdentifierListItem.Create( + NewItem:=CIdentifierListItem.Create( icompUnknown, false, 0, @@ -1306,7 +1336,7 @@ procedure TIdentCompletionTool.GatherPredefinedIdentifiers(CleanPos: integer; var NewItem: TIdentifierListItem; begin - NewItem:=TIdentifierListItem.Create( + NewItem:=CUnitNameSpaceIdentifierListItem.Create( icompUnknown, false, CompilerFuncHistoryIndex, @@ -1314,7 +1344,9 @@ procedure TIdentCompletionTool.GatherPredefinedIdentifiers(CleanPos: integer; CompilerFuncLevel, nil, nil, - ctnUseUnitClearName); + ctnUseUnitClearName, + AnUnitName, + 1); CurrentIdentifierList.Add(NewItem); end; @@ -1396,7 +1428,7 @@ begin and Context.Tool.NodeIsInAMethod(Context.Node) and (not CurrentIdentifierList.HasIdentifier('Self','')) then begin // method body -> add 'Self' - NewItem:=TIdentifierListItem.Create( + NewItem:=CIdentifierListItem.Create( icompUnknown, true, 1, @@ -1412,7 +1444,7 @@ begin and Context.Tool.NodeIsFunction(ProcNode) and (not CurrentIdentifierList.HasIdentifier('Result','')) then begin // function body -> add 'Result' - NewItem:=TIdentifierListItem.Create( + NewItem:=CIdentifierListItem.Create( icompUnknown, true, 1, @@ -1466,7 +1498,7 @@ procedure TIdentCompletionTool.GatherUsefulIdentifiers(CleanPos: integer; var NewItem: TIdentifierListItem; begin - NewItem:=TIdentifierListItem.Create( + NewItem:=CIdentifierListItem.Create( icompExact,true,0, CurrentIdentifierList.CreateIdentifier(ProcName), 0,nil,nil,ctnProcedure); @@ -1556,13 +1588,10 @@ begin if CompareText(PChar(Pointer(UnitFileInfo.FileUnitName)), Length(UnitFileInfo.FileUnitName), PChar(Pointer(CurSourceName)), Length(CurSourceName), False)<>0 then begin - // oooooo - NewItem:=TUnitNameSpaceIdentifierListItem.Create( + NewItem:=CUnitNameSpaceIdentifierListItem.Create( icompCompatible,true,0, CurrentIdentifierList.CreateIdentifier(UnitFileInfo.FileUnitNameWithoutNamespace), - 0,nil,nil,ctnUnit); - NewItem.UnitFileName := UnitFileInfo.Filename; - NewItem.IdentifierStartInUnitName := UnitFileInfo.IdentifierStartInUnitName; + 0,nil,nil,ctnUnit, PChar(UnitFileInfo.FileUnitName), UnitFileInfo.IdentifierStartInUnitName); if NewItem.IdentifierStartInUnitName < 1 then NewItem.IdentifierStartInUnitName := 1; CurrentIdentifierList.Add(NewItem); @@ -1575,12 +1604,11 @@ begin ANode:=FIDTTreeOfNamespaces.FindLowest; while ANode<>nil do begin NameSpaceInfo:=TNameSpaceInfo(ANode.Data); - NewItem:=TUnitNameSpaceIdentifierListItem.Create( + NewItem:=CUnitNameSpaceIdentifierListItem.Create( icompCompatible,true,0, CurrentIdentifierList.CreateIdentifier(NameSpaceInfo.NameSpace), - 0,nil,nil,ctnUseUnitNamespace); - NewItem.UnitFileName := NameSpaceInfo.Filename; - NewItem.IdentifierStartInUnitName := NameSpaceInfo.IdentifierStartInUnitName; + 0,nil,nil,ctnUseUnitNamespace, PChar(NameSpaceInfo.UnitName), + NameSpaceInfo.IdentifierStartInUnitName); CurrentIdentifierList.Add(NewItem); ANode:=FIDTTreeOfNamespaces.FindSuccessor(ANode); end; @@ -1597,7 +1625,7 @@ procedure TIdentCompletionTool.GatherSourceNames(const Context: TFindContext); var NewItem: TIdentifierListItem; begin - NewItem:=TIdentifierListItem.Create( + NewItem:=CIdentifierListItem.Create( icompExact,true,0, CurrentIdentifierList.CreateIdentifier(SrcName), 0,nil,nil,Context.Node.Desc); @@ -1643,7 +1671,7 @@ type NewItem: TIdentifierListItem; begin KeyWord:=BeautifyCodeOptions.BeautifyKeyWord(Keyword); - NewItem:=TIdentifierListItem.Create( + NewItem:=CIdentifierListItem.Create( icompExact,false,0, CurrentIdentifierList.CreateIdentifier(Keyword), 1000,nil,nil,ctnNone); @@ -3549,6 +3577,11 @@ begin +' "'+StringToPascalConst(copy(Tool.Src,ANode.StartPos,50))+'"'; end; +procedure TIdentifierListItem.BeautifyIdentifier(IdentList: TIdentifierList); +begin + // can be overridden +end; + function TIdentifierListItem.GetDesc: TCodeTreeNodeDesc; var ANode: TCodeTreeNode; diff --git a/ide/sourceeditprocs.pas b/ide/sourceeditprocs.pas index 2bc2e62652..08818934f5 100644 --- a/ide/sourceeditprocs.pas +++ b/ide/sourceeditprocs.pas @@ -67,7 +67,21 @@ type out CodeBuffer: Pointer): boolean; override; procedure AssignCodeToolBossError(Target: TCustomTextConverterTool); override; end; - + + TLazIdentifierListItem = class(TIdentifierListItem) + private + FBeautified: Boolean; + public + procedure BeautifyIdentifier({%H-}IdentList: TIdentifierList); override; + end; + + TLazUnitNameSpaceIdentifierListItem = class(TUnitNameSpaceIdentifierListItem) + private + FBeautified: Boolean; + public + procedure BeautifyIdentifier(IdentList: TIdentifierList); override; + end; + procedure SetupTextConverters; procedure FreeTextConverters; @@ -251,6 +265,7 @@ begin ACanvas.TextOut(x+1, y, 'PaintCompletionItem: BUG in codetools or misuse of PaintCompletionItem'); exit; end; + IdentItem.BeautifyIdentifier(CodeToolBoss.IdentifierList); BackgroundColor:=ColorToRGB(ACanvas.Brush.Color); BGRed:=(BackgroundColor shr 16) and $ff; BGGreen:=(BackgroundColor shr 8) and $ff; @@ -360,8 +375,6 @@ begin SetFontColor(ForegroundColor); ACanvas.Font.Style:=ACanvas.Font.Style+[fsBold]; s:=IdentItem.Identifier; - with CodeToolBoss.SourceChangeCache.BeautifyCodeOptions do - WordExceptions.CheckExceptions(s); if MeasureOnly then Inc(Result.X, 1+ACanvas.TextWidth(s)) else begin @@ -546,35 +559,6 @@ begin end; end; -function FindUnitName(IdentList: TIdentifierList; - IdentItem: TIdentifierListItem): string; -var - CodeBuf: TCodeBuffer; - LastPointPos: Integer; -begin - Result:=IdentItem.Identifier; - if IdentItem is TUnitNameSpaceIdentifierListItem then - begin - CodeBuf:=CodeToolBoss.FindFile(TUnitNameSpaceIdentifierListItem(IdentItem).UnitFileName); - if CodeBuf=nil then Exit; - Result:=CodeToolBoss.GetSourceName(CodeBuf,true); - Result:=Copy(CodeToolBoss.GetSourceName(CodeBuf,true), TUnitNameSpaceIdentifierListItem(IdentItem).IdentifierStartInUnitName, Length(IdentItem.Identifier)); - end else - begin - CodeBuf:=CodeToolBoss.FindUnitSource(IdentList.StartContextPos.Code,Result,''); - if CodeBuf=nil then Exit; - Result:=CodeToolBoss.GetSourceName(CodeBuf,true); - end; - if Result='' then - Result:=IdentItem.Identifier - else - begin - LastPointPos := LastDelimiter('.', Result); - if LastPointPos > 0 then - Result := Copy(Result, LastPointPos+1, High(Integer)); - end; -end; - function GetIdentCompletionValue(aCompletion : TSynCompletion; AddChar: TUTF8Char; out ValueType: TIdentComplValue; out CursorToLeft: integer): string; @@ -593,7 +577,6 @@ var Indent: LongInt; StartContextPos: TCodeXYPosition; s: String; - IsWordPolicyExcept: Boolean; begin Result:=''; CursorToLeft:=0; @@ -608,6 +591,7 @@ begin exit; end; + IdentItem.BeautifyIdentifier(IdentList); CodeToolBoss.IdentItemCheckHasChilds(IdentItem); CanAddSemicolon:=CodeToolsOpts.IdentComplAddSemicolon and (AddChar<>';'); @@ -615,8 +599,6 @@ begin IsReadOnly:=false; Result:=IdentItem.Identifier; - with CodeToolBoss.SourceChangeCache.BeautifyCodeOptions do - IsWordPolicyExcept:=WordExceptions.CheckExceptions(Result); //debugln(['GetIdentCompletionValue IdentItem.GetDesc=',NodeDescriptionAsString(IdentItem.GetDesc),' IdentList.ContextFlags=',dbgs(IdentList.ContextFlags),' IdentItem.Node=',IdentItem.Node<>nil]); @@ -721,10 +703,6 @@ begin //debugln(['GetIdentCompletionValue ',dbgstr(Result),' LineLen=',CodeToolBoss.SourceChangeCache.BeautifyCodeOptions.LineLength]); CanAddSemicolon:=false; end; - - icvUnitName: - if not IsWordPolicyExcept then - Result:=FindUnitName(IdentList,IdentItem); end; if CursorAtEnd then ; @@ -864,6 +842,50 @@ begin SynREEngine.Split(TheText,Pieces); end; +{ TLazIdentifierListItem } + +procedure TLazIdentifierListItem.BeautifyIdentifier(IdentList: TIdentifierList); +begin + if FBeautified then + Exit; + + CodeToolBoss.SourceChangeCache.BeautifyCodeOptions.WordExceptions.CheckExceptions(Identifier); + FBeautified:=True; +end; + +{ TLazUnitNameSpaceIdentifierListItem } + +procedure TLazUnitNameSpaceIdentifierListItem.BeautifyIdentifier( + IdentList: TIdentifierList); +var + CodeBuf: TCodeBuffer; + LastPointPos: Integer; + NewIdentifier: string; +begin + if FBeautified then + Exit; + + NewIdentifier:=Identifier; + if not CodeToolBoss.SourceChangeCache.BeautifyCodeOptions.WordExceptions.CheckExceptions(NewIdentifier) then + begin + CodeBuf:=CodeToolBoss.FindUnitSource(IdentList.StartContextPos.Code,FileUnitName,''); + if CodeBuf=nil then Exit; + + NewIdentifier:=Copy(CodeToolBoss.GetSourceName(CodeBuf,true), IdentifierStartInUnitName, Length(Identifier)); + + if NewIdentifier='' then + NewIdentifier:=Identifier + else + begin + LastPointPos := LastDelimiter('.', NewIdentifier); + if LastPointPos > 0 then + NewIdentifier := Copy(NewIdentifier, LastPointPos+1, High(Integer)); + end; + end; + Identifier := NewIdentifier; + FBeautified := True; +end; + { TLazTextConverterToolClasses } function TLazTextConverterToolClasses.GetTempFilename: string; @@ -986,6 +1008,8 @@ initialization REVarCountFunction:=@SynREVarCount; REReplaceProcedure:=@SynREReplace; RESplitFunction:=@SynRESplit; + CIdentifierListItem:=TLazIdentifierListItem; + CUnitNameSpaceIdentifierListItem:=TLazUnitNameSpaceIdentifierListItem; finalization FreeAndNil(SynREEngine);