codetools: find protected members in class helpers, bug #28810, patch from Ondrej

git-svn-id: trunk@50115 -
This commit is contained in:
mattias 2015-10-18 22:27:22 +00:00
parent ea4449e888
commit 3b84c9a585
6 changed files with 67 additions and 20 deletions

1
.gitattributes vendored
View File

@ -1012,6 +1012,7 @@ components/codetools/tests/fpctests/tchlp52.pp svneol=native#text/plain
components/codetools/tests/fpctests/tchlp53.pp svneol=native#text/plain
components/codetools/tests/fpctests/tchlp6.pp svneol=native#text/plain
components/codetools/tests/fpctests/tchlp7.pp svneol=native#text/plain
components/codetools/tests/fpctests/uchlp12.pp svneol=native#text/plain
components/codetools/tests/laztests/README.txt svneol=native#text/plain
components/codetools/tests/laztests/bug28861_unit1.pas svneol=native#text/plain
components/codetools/tests/laztests/bug28861_unit2.pas svneol=native#text/plain

View File

@ -893,9 +893,9 @@ type
// ancestors
function FindClassAndAncestors(ClassNode: TCodeTreeNode;
out ListOfPFindContext: TFPList; ExceptionOnNotFound: boolean
var ListOfPFindContext: TFPList; ExceptionOnNotFound: boolean
): boolean; // without interfaces, recursive
function FindContextClassAndAncestors(const CursorPos: TCodeXYPosition;
function FindContextClassAndAncestorsAndExtendedClassOfHelper(const CursorPos: TCodeXYPosition;
var ListOfPFindContext: TFPList): boolean; // without interfaces
function FindAncestorOfClass(ClassNode: TCodeTreeNode;
Params: TFindDeclarationParams; FindClassContext: boolean): boolean; // returns false for TObject, IInterface, IUnknown
@ -4950,7 +4950,7 @@ begin
end;
function TFindDeclarationTool.FindClassAndAncestors(ClassNode: TCodeTreeNode;
out ListOfPFindContext: TFPList; ExceptionOnNotFound: boolean): boolean;
var ListOfPFindContext: TFPList; ExceptionOnNotFound: boolean): boolean;
var
Params: TFindDeclarationParams;
@ -4979,7 +4979,6 @@ var
begin
{$IFDEF CheckNodeTool}CheckNodeTool(ClassNode);{$ENDIF}
Result:=false;
ListOfPFindContext:=nil;
if (ClassNode=nil) or (not (ClassNode.Desc in AllClasses))
or (ClassNode.Parent=nil)
or (not (ClassNode.Parent.Desc in [ctnTypeDefinition,ctnGenericType])) then
@ -5076,14 +5075,14 @@ begin
end;
end;
function TFindDeclarationTool.FindContextClassAndAncestors(
const CursorPos: TCodeXYPosition; var ListOfPFindContext: TFPList
): boolean;
function TFindDeclarationTool.FindContextClassAndAncestorsAndExtendedClassOfHelper
(const CursorPos: TCodeXYPosition; var ListOfPFindContext: TFPList): boolean;
// returns a list of nodes of AllClasses (ctnClass, ...)
var
CleanCursorPos: integer;
ANode: TCodeTreeNode;
ClassNode: TCodeTreeNode;
ExtendedClassExpr: TExpressionType;
begin
Result:=false;
ListOfPFindContext:=nil;
@ -5107,6 +5106,15 @@ begin
if not FindClassAndAncestors(ClassNode,ListOfPFindContext,true)
then exit;
//find extended class node
ExtendedClassExpr := FindExtendedExprOfHelper(ClassNode);
if ((ExtendedClassExpr.Desc=xtContext) and (ExtendedClassExpr.Context.Tool<>nil) and
(ExtendedClassExpr.Context.Node<>nil) and (ExtendedClassExpr.Context.Node.Desc=ctnClass)) then
begin
if not ExtendedClassExpr.Context.Tool.FindClassAndAncestors(ExtendedClassExpr.Context.Node,ListOfPFindContext,true)
then exit;
end;
//debugln('TFindDeclarationTool.FindContextClassAndAncestors List: ',ListOfPFindContextToStr(ListOfPFindContext));
finally

View File

@ -355,7 +355,7 @@ type
FBeautifier: TBeautifyCodeOptions;
FLastGatheredIdentParent: TCodeTreeNode;
FLastGatheredIdentLevel: integer;
FICTClassAndAncestors: TFPList;// list of PCodeXYPosition
FICTClassAndAncestorsAndExtClassOfHelper: TFPList;// list of PCodeXYPosition
FIDCTFoundPublicProperties: TAVLTree;// tree of PChar (pointing to the
// property names in source)
FIDTFoundMethods: TAVLTree;// tree of TCodeTreeNodeExtension Txt=clean text
@ -1009,7 +1009,7 @@ var
FoundClassContext: TFindContext;
begin
Result:=false;
if FICTClassAndAncestors<>nil then begin
if (FICTClassAndAncestorsAndExtClassOfHelper<>nil) then begin
// start of the identifier completion is in a method or class
// => all protected ancestor classes are allowed as well.
CurClassNode:=FoundContext.Node;
@ -1018,8 +1018,8 @@ var
CurClassNode:=CurClassNode.Parent;
if CurClassNode=nil then exit;
FoundClassContext:=CreateFindContext(Params.NewCodeTool,CurClassNode);
if IndexOfFindContext(FICTClassAndAncestors,@FoundClassContext)>=0 then begin
// this class node is the class or one of the ancestors of the class
if IndexOfFindContext(FICTClassAndAncestorsAndExtClassOfHelper,@FoundClassContext)>=0 then begin
// this class node is the class or one of the ancestors of the class or extended class of the helper+ancestors
// of the start context of the identifier completion
exit(true);
end;
@ -2576,7 +2576,9 @@ begin
GatherContext := ExprType.Context;
// find class and ancestors if existing (needed for protected identifiers)
if GatherContext.Tool = Self then
FindContextClassAndAncestors(IdentStartXY, FICTClassAndAncestors);
begin
FindContextClassAndAncestorsAndExtendedClassOfHelper(IdentStartXY, FICTClassAndAncestorsAndExtClassOfHelper);
end;
CursorContext:=CreateFindContext(Self,CursorNode);
GatherContextKeywords(CursorContext,IdentStartPos,Beautifier);
@ -2756,7 +2758,7 @@ begin
Result:=true;
finally
FreeListOfPFindContext(FICTClassAndAncestors);
FreeListOfPFindContext(FICTClassAndAncestorsAndExtClassOfHelper);
FreeAndNil(FIDCTFoundPublicProperties);
Params.Free;
ClearIgnoreErrorAfter;
@ -2959,7 +2961,7 @@ begin
if IdentEndPos=0 then ;
// find class and ancestors if existing (needed for protected identifiers)
FindContextClassAndAncestors(CursorPos,FICTClassAndAncestors);
FindContextClassAndAncestorsAndExtendedClassOfHelper(CursorPos,FICTClassAndAncestorsAndExtClassOfHelper);
if CursorNode<>nil then begin
if not CheckContextIsParameter(Result) then begin
@ -2981,7 +2983,7 @@ begin
end else begin
FreeAndNil(CurrentIdentifierContexts);
end;
FreeListOfPFindContext(FICTClassAndAncestors);
FreeListOfPFindContext(FICTClassAndAncestorsAndExtClassOfHelper);
FreeAndNil(FIDCTFoundPublicProperties);
Params.Free;
ClearIgnoreErrorAfter;
@ -3324,9 +3326,9 @@ var
m: PtrUint;
begin
inherited CalcMemSize(Stats);
if FICTClassAndAncestors<>nil then
Stats.Add('TIdentCompletionTool.ClassAndAncestors',
FICTClassAndAncestors.Count*(SizeOf(TAVLTreeNode)+SizeOf(TCodeXYPosition)));
if FICTClassAndAncestorsAndExtClassOfHelper<>nil then
Stats.Add('TIdentCompletionTool.ClassAndAncestorsAndExtClassOfHelper',
FICTClassAndAncestorsAndExtClassOfHelper.Count*(SizeOf(TAVLTreeNode)+SizeOf(TCodeXYPosition)));
if FIDCTFoundPublicProperties<>nil then
Stats.Add('TIdentCompletionTool.FoundPublicProperties',
FIDCTFoundPublicProperties.Count*SizeOf(TAVLTreeNode));

View File

@ -18,7 +18,7 @@ type
function TTestHelper.AccessTest: Integer;
begin
Result := Test3;
Result := Test3{declaration:uchlp12.TTest.test3};
end;
begin

View File

@ -18,7 +18,7 @@ type
function TTestHelper.AccessTest: Integer;
begin
Result := Test4;
Result := Test4{declaration:uchlp12.TTest.test4};
end;
begin

View File

@ -0,0 +1,36 @@
unit uchlp12;
{$ifdef fpc}
{$mode delphi}
{$endif}
interface
type
{$M+}
TTest = class
private
function GetTest6: Integer;
strict private
Test1: Integer;
private
Test2: Integer;
strict protected
Test3: Integer;
protected
Test4: Integer;
public
Test5: Integer;
published
property Test6: Integer read GetTest6;
end;
{$M-}
implementation
function TTest.GetTest6: Integer;
begin
Result := 0;
end;
end.