codetools: parsing specialize in class inheritage brackets, bug #15081

git-svn-id: trunk@22649 -
This commit is contained in:
mattias 2009-11-17 12:11:33 +00:00
parent f76a696f9c
commit 837f13ad0c
5 changed files with 116 additions and 86 deletions

View File

@ -374,14 +374,18 @@ begin
end;
ClearIgnoreErrorAfter;
BuildSubTreeForClass(FCodeCompleteClassNode);
if FCodeCompleteClassNode.Desc in AllClassInterfaces then
FCompletingStartNode:=FCodeCompleteClassNode
else
FCompletingStartNode:=FCodeCompleteClassNode.FirstChild;
while (FCompletingStartNode<>nil) and (FCompletingStartNode.FirstChild=nil) do
FCompletingStartNode:=FCompletingStartNode.NextBrother;
if FCompletingStartNode<>nil then
FCompletingStartNode:=FCompletingStartNode.FirstChild;
// find first variable/method/GUID
FCompletingStartNode:=FCodeCompleteClassNode.FirstChild;
while FCompletingStartNode<>nil do begin
if FCompletingStartNode.Desc in AllClassSections then
FCompletingStartNode:=FCompletingStartNode.Next
else if FCompletingStartNode.Desc in (AllIdentifierDefinitions
+[ctnProperty,ctnProcedure])
then
break
else
FCompletingStartNode:=FCompletingStartNode.NextBrother;
end;
end;
procedure TCodeCompletionCodeTool.SetCodeCompleteSrcChgCache(

View File

@ -1280,8 +1280,7 @@ var CleanCursorPos: integer;
// parse class and build CodeTreeNodes for all properties/methods
BuildSubTreeForClass(ClassNode);
CursorNode:=FindDeepestNodeAtPos(ClassNode,CleanCursorPos,true);
if (CursorNode.Desc=ctnClassInheritance)
or (CursorNode.Parent.Desc=ctnClassInheritance) then begin
if CursorNode.GetNodeOfType(ctnClassInheritance)<>nil then begin
// identifier is an ancestor/interface identifier
CursorNode:=ClassNode.Parent;
DirectSearch:=true;
@ -3812,8 +3811,7 @@ begin
// find class node
ANode:=FindDeepestNodeAtPos(CleanCursorPos,true);
if (ANode.Desc=ctnClassInheritance)
or ((ANode.Parent<>nil) and (ANode.Parent.Desc=ctnClassInheritance)) then
if (ANode.GetNodeOfType(ctnClassInheritance)<>nil) then
exit;
ClassNode:=FindClassNode(ANode);
if (ClassNode=nil) or (ClassNode.Parent=nil)
@ -4770,7 +4768,7 @@ var
begin
{$IFDEF CheckNodeTool}CheckNodeTool(IdentifierNode);{$ENDIF}
if (IdentifierNode=nil)
or (IdentifierNode.Desc<>ctnIdentifier)
or (not (IdentifierNode.Desc in [ctnIdentifier,ctnSpecialize]))
or (IdentifierNode.Parent=nil)
or (IdentifierNode.Parent.Desc<>ctnClassInheritance)
then
@ -4781,7 +4779,16 @@ begin
ClassNode:=IdentifierNode.Parent.Parent;
ClassIdentNode:=ClassNode.Parent;
MoveCursorToCleanPos(IdentifierNode.StartPos);
if IdentifierNode.Desc=ctnSpecialize then begin
if (IdentifierNode.FirstChild=nil) then begin
MoveCursorToCleanPos(IdentifierNode.StartPos);
ReadNextAtom;
ReadNextAtom;
RaiseStringExpectedButAtomFound('class type');
end;
MoveCursorToCleanPos(IdentifierNode.FirstChild.StartPos);
end else
MoveCursorToCleanPos(IdentifierNode.StartPos);
AncestorStartPos:=CurPos.StartPos;
ReadNextAtom;
AtomIsIdentifier(true);

View File

@ -1587,10 +1587,8 @@ begin
else
GatherContext.Node:=GatherContext.Node.Parent;
end
else if (GatherContext.Node.Desc=ctnClassInheritance)
or ((GatherContext.Node.Parent<>nil)
and (GatherContext.Node.Parent.Desc=ctnClassInheritance))
then begin
else if (GatherContext.Node.GetNodeOfType(ctnClassInheritance)<>nil) then
begin
while not (GatherContext.Node.Desc in AllClasses) do
GatherContext.Node:=GatherContext.Node.Parent;
GatherContext.Node:=GatherContext.Node.Parent;

View File

@ -780,7 +780,6 @@ begin
Result:=TAVLTree.Create(@CompareCodeTreeNodeExt);
ANode:=StartNode;
while (ANode<>nil) do begin
//DebugLn('[TMethodJumpingCodeTool.GatherProcNodes] A ',NodeDescriptionAsString(ANode.Desc));
if ANode.Desc=ctnProcedure then begin
if (not ((phpIgnoreForwards in Attr)
and ((ANode.SubDesc and ctnsForwardDeclaration)>0)))

View File

@ -201,6 +201,7 @@ type
function ReadTilTypeOfProperty(PropertyNode: TCodeTreeNode): boolean;
procedure ReadGUID;
procedure ReadClassInheritance(CreateChildNodes: boolean);
procedure ReadSpecialize(CreateChildNodes: boolean);
function WordIsPropertyEnd: boolean;
public
CurSection: TCodeTreeNodeDesc;
@ -3309,61 +3310,8 @@ begin
end;
function TPascalParserTool.KeyWordFuncSpecialize: boolean;
// specialize template
// examples:
// type TListOfInteger = specialize TGenericList<integer,string>;
// type TListOfChar = specialize Classes.TGenericList<integer,objpas.integer>;
begin
if (CurNode.Desc<>ctnTypeDefinition) then
SaveRaiseExceptionFmt(ctsAnonymDefinitionsAreNotAllowed,['specialize']);
CreateChildNode;
CurNode.Desc:=ctnSpecialize;
// read identifier (the name of the generic)
ReadNextAtom;
AtomIsIdentifier(true);
CreateChildNode;
CurNode.Desc:=ctnSpecializeType;
CurNode.EndPos:=CurPos.EndPos;
ReadNextAtom;
if Curpos.Flag=cafPoint then begin
// first identifier was unitname, now read the type
ReadNextAtom;
AtomIsIdentifier(true);
CurNode.EndPos:=CurPos.EndPos;
ReadNextAtom;
end;
EndChildNode;
// read type list
if not AtomIsChar('<') then
RaiseCharExpectedButAtomFound('<');
CreateChildNode;
CurNode.Desc:=ctnSpecializeParams;
// read list of types
repeat
// read identifier (a parameter of the generic type)
ReadNextAtom;
AtomIsIdentifier(true);
ReadNextAtom;
if Curpos.Flag=cafPoint then begin
// first identifier was unitname, now read the type
ReadNextAtom;
AtomIsIdentifier(true);
ReadNextAtom;
end;
if AtomIsChar('>') then
break
else if CurPos.Flag=cafComma then begin
// read next parameter
end else
RaiseCharExpectedButAtomFound('>');
until false;
// close list
CurNode.EndPos:=CurPos.EndPos;
EndChildNode;
// close specialize
CurNode.EndPos:=CurPos.EndPos;
EndChildNode;
ReadNextAtom;
ReadSpecialize(true);
Result:=true;
end;
@ -4419,21 +4367,26 @@ begin
ReadNextAtom;
if CurPos.Flag<>cafRoundBracketClose then begin
repeat
// read Identifier or Unit.Identifier
AtomIsIdentifier(true);
if CreateChildNodes then begin
CreateChildNode;
CurNode.Desc:=ctnIdentifier;
end;
ReadNextAtom;
if CurPos.Flag=cafPoint then begin
ReadNextAtom;
if UpAtomIs('SPECIALIZE') then begin
// specialize Identifier<Identifier>
ReadSpecialize(CreateChildNodes);
end else begin
// read Identifier or Unit.Identifier
AtomIsIdentifier(true);
if CreateChildNodes then begin
CreateChildNode;
CurNode.Desc:=ctnIdentifier;
end;
ReadNextAtom;
end;
if CreateChildNodes then begin
CurNode.EndPos:=CurPos.EndPos;
EndChildNode;
if CurPos.Flag=cafPoint then begin
ReadNextAtom;
AtomIsIdentifier(true);
ReadNextAtom;
end;
if CreateChildNodes then begin
CurNode.EndPos:=CurPos.EndPos;
EndChildNode;
end;
end;
// read comma or )
if CurPos.Flag=cafRoundBracketClose then break;
@ -4449,6 +4402,75 @@ begin
end;
end;
procedure TPascalParserTool.ReadSpecialize(CreateChildNodes: boolean);
// specialize template
// after parsing the cursor is on the atom behind the >
// examples:
// type TListOfInteger = specialize TGenericList<integer,string>;
// type TListOfChar = specialize Classes.TGenericList<integer,objpas.integer>;
// type l = class(specialize TFPGObjectList<TControl>)
begin
if CreateChildNodes then begin
CreateChildNode;
CurNode.Desc:=ctnSpecialize;
end;
// read identifier (the name of the generic)
ReadNextAtom;
AtomIsIdentifier(true);
if CreateChildNodes then begin
CreateChildNode;
CurNode.Desc:=ctnSpecializeType;
CurNode.EndPos:=CurPos.EndPos;
end;
ReadNextAtom;
if Curpos.Flag=cafPoint then begin
// first identifier was unitname, now read the type
ReadNextAtom;
AtomIsIdentifier(true);
if CreateChildNodes then
CurNode.EndPos:=CurPos.EndPos;
ReadNextAtom;
end;
if CreateChildNodes then begin
EndChildNode; // end ctnSpecializeType
end;
// read type list
if not AtomIsChar('<') then
RaiseCharExpectedButAtomFound('<');
if CreateChildNodes then begin
CreateChildNode;
CurNode.Desc:=ctnSpecializeParams;
end;
// read list of types
repeat
// read identifier (a parameter of the generic type)
ReadNextAtom;
AtomIsIdentifier(true);
ReadNextAtom;
if Curpos.Flag=cafPoint then begin
// first identifier was unitname, now read the type
ReadNextAtom;
AtomIsIdentifier(true);
ReadNextAtom;
end;
if AtomIsChar('>') then
break
else if CurPos.Flag=cafComma then begin
// read next parameter
end else
RaiseCharExpectedButAtomFound('>');
until false;
if CreateChildNodes then begin
// close list
CurNode.EndPos:=CurPos.EndPos;
EndChildNode; // end ctnSpecializeParams
// close specialize
CurNode.EndPos:=CurPos.EndPos;
EndChildNode; // end ctnSpecialize
end;
ReadNextAtom;
end;
function TPascalParserTool.WordIsPropertyEnd: boolean;
var
p: PChar;