mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-08 05:19:08 +02:00
MG: find declaration of class ancestor, result type, default property, array, indexed pointer
git-svn-id: trunk@602 -
This commit is contained in:
parent
eb66cd1363
commit
147fbd54ee
@ -52,55 +52,56 @@ const
|
|||||||
// CodeTreeNodeDescriptors
|
// CodeTreeNodeDescriptors
|
||||||
ctnNone = 0;
|
ctnNone = 0;
|
||||||
|
|
||||||
ctnClass = 1;
|
ctnProgram = 1;
|
||||||
ctnClassPublished = 2;
|
ctnPackage = 2;
|
||||||
ctnClassPrivate = 3;
|
ctnLibrary = 3;
|
||||||
ctnClassProtected = 4;
|
ctnUnit = 4;
|
||||||
ctnClassPublic = 5;
|
ctnInterface = 5;
|
||||||
|
ctnImplementation = 6;
|
||||||
|
ctnInitialization = 7;
|
||||||
|
ctnFinalization = 8;
|
||||||
|
|
||||||
ctnProcedure = 10;
|
ctnTypeSection = 10;
|
||||||
ctnProcedureHead = 11;
|
ctnVarSection = 11;
|
||||||
ctnParameterList = 12;
|
ctnConstSection = 12;
|
||||||
|
ctnResStrSection = 13;
|
||||||
|
ctnUsesSection = 14;
|
||||||
|
|
||||||
ctnBeginBlock = 20;
|
ctnTypeDefinition = 20;
|
||||||
ctnAsmBlock = 21;
|
ctnVarDefinition = 21;
|
||||||
|
ctnConstDefinition = 22;
|
||||||
|
|
||||||
ctnProgram = 30;
|
ctnClass = 30;
|
||||||
ctnPackage = 31;
|
ctnClassPublished = 31;
|
||||||
ctnLibrary = 32;
|
ctnClassPrivate = 32;
|
||||||
ctnUnit = 33;
|
ctnClassProtected = 33;
|
||||||
ctnInterface = 34;
|
ctnClassPublic = 34;
|
||||||
ctnImplementation = 35;
|
|
||||||
ctnInitialization = 36;
|
|
||||||
ctnFinalization = 37;
|
|
||||||
|
|
||||||
ctnTypeSection = 40;
|
ctnProperty = 40;
|
||||||
ctnVarSection = 41;
|
|
||||||
ctnConstSection = 42;
|
|
||||||
ctnResStrSection = 43;
|
|
||||||
ctnUsesSection = 44;
|
|
||||||
|
|
||||||
ctnTypeDefinition = 50;
|
|
||||||
ctnVarDefinition = 51;
|
|
||||||
ctnConstDefinition = 52;
|
|
||||||
|
|
||||||
ctnProperty = 60;
|
|
||||||
|
|
||||||
ctnIdentifier = 70;
|
ctnProcedure = 50;
|
||||||
ctnArrayType = 71;
|
ctnProcedureHead = 51;
|
||||||
ctnRecordType = 72;
|
ctnParameterList = 52;
|
||||||
ctnRecordCase = 73;
|
|
||||||
ctnRecordVariant = 74;
|
ctnIdentifier = 60;
|
||||||
ctnProcedureType = 75;
|
ctnArrayType = 61;
|
||||||
ctnSetType = 76;
|
ctnOfConstType = 62;
|
||||||
ctnRangeType = 77;
|
ctnRecordType = 63;
|
||||||
ctnEnumType = 78;
|
ctnRecordCase = 64;
|
||||||
ctnLabelType = 79;
|
ctnRecordVariant = 65;
|
||||||
ctnTypeType = 80;
|
ctnProcedureType = 66;
|
||||||
ctnFileType = 81;
|
ctnSetType = 67;
|
||||||
ctnPointerType = 82;
|
ctnRangeType = 68;
|
||||||
ctnClassOfType = 83;
|
ctnEnumType = 69;
|
||||||
|
ctnLabelType = 70;
|
||||||
|
ctnTypeType = 71;
|
||||||
|
ctnFileType = 72;
|
||||||
|
ctnPointerType = 73;
|
||||||
|
ctnClassOfType = 74;
|
||||||
|
|
||||||
|
ctnBeginBlock = 80;
|
||||||
|
ctnAsmBlock = 81;
|
||||||
|
|
||||||
ctnWithVariable = 90;
|
ctnWithVariable = 90;
|
||||||
ctnWithStatement = 91;
|
ctnWithStatement = 91;
|
||||||
|
|
||||||
@ -123,8 +124,9 @@ const
|
|||||||
|
|
||||||
|
|
||||||
// CodeTreeNodeSubDescriptors
|
// CodeTreeNodeSubDescriptors
|
||||||
ctnsNone = 0;
|
ctnsNone = 0;
|
||||||
ctnsForwardDeclaration = 1;
|
ctnsForwardDeclaration = 1;
|
||||||
|
ctnsProcHeadNodesCreated = 2;
|
||||||
|
|
||||||
type
|
type
|
||||||
TCodeTreeNode = class
|
TCodeTreeNode = class
|
||||||
@ -548,7 +550,7 @@ begin
|
|||||||
FCount:=0;
|
FCount:=0;
|
||||||
FAllocatedNodes:=0;
|
FAllocatedNodes:=0;
|
||||||
FFreedNodes:=0;
|
FFreedNodes:=0;
|
||||||
FMinFree:=10000;
|
FMinFree:=100000;
|
||||||
FMaxFreeRatio:=8; // 1:1
|
FMaxFreeRatio:=8; // 1:1
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -626,7 +628,7 @@ begin
|
|||||||
FFirstFree:=nil;
|
FFirstFree:=nil;
|
||||||
FFreeCount:=0;
|
FFreeCount:=0;
|
||||||
FCount:=0;
|
FCount:=0;
|
||||||
FMinFree:=10000;
|
FMinFree:=20000;
|
||||||
FMaxFreeRatio:=8; // 1:1
|
FMaxFreeRatio:=8; // 1:1
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -224,6 +224,10 @@ begin
|
|||||||
// CodeTreeNodeSubDescriptors
|
// CodeTreeNodeSubDescriptors
|
||||||
ctnsForwardDeclaration : Result:='Forward';
|
ctnsForwardDeclaration : Result:='Forward';
|
||||||
end;
|
end;
|
||||||
|
ctnProcedureHead:
|
||||||
|
case SubDesc of
|
||||||
|
ctnsProcHeadNodesCreated: Result:='Nodes Created';
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -596,13 +596,21 @@ if (ContextNode.Desc=ctnClass) then
|
|||||||
ctnInterface, ctnImplementation,
|
ctnInterface, ctnImplementation,
|
||||||
ctnClassPublic, ctnClassPrivate, ctnClassProtected, ctnClassPublished,
|
ctnClassPublic, ctnClassPrivate, ctnClassProtected, ctnClassPublished,
|
||||||
ctnClass,
|
ctnClass,
|
||||||
ctnRecordType, ctnRecordCase, ctnRecordVariant:
|
ctnRecordType, ctnRecordCase, ctnRecordVariant,
|
||||||
|
ctnParameterList:
|
||||||
if (ContextNode.LastChild<>nil) then begin
|
if (ContextNode.LastChild<>nil) then begin
|
||||||
if not (fdfSearchForward in Params.Flags) then
|
if not (fdfSearchForward in Params.Flags) then
|
||||||
ContextNode:=ContextNode.LastChild
|
ContextNode:=ContextNode.LastChild
|
||||||
else
|
else
|
||||||
ContextNode:=ContextNode.FirstChild;
|
ContextNode:=ContextNode.FirstChild;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
ctnProcedureHead:
|
||||||
|
begin
|
||||||
|
BuildSubTreeForProcHead(ContextNode);
|
||||||
|
if ContextNode.FirstChild<>nil then
|
||||||
|
ContextNode:=ContextNode.FirstChild;
|
||||||
|
end;
|
||||||
|
|
||||||
ctnTypeDefinition, ctnVarDefinition, ctnConstDefinition, ctnEnumType:
|
ctnTypeDefinition, ctnVarDefinition, ctnConstDefinition, ctnEnumType:
|
||||||
begin
|
begin
|
||||||
@ -645,15 +653,21 @@ writeln(' Definition Identifier found=',copy(Src,ContextNode.StartPos,Params.Id
|
|||||||
|
|
||||||
ctnProperty:
|
ctnProperty:
|
||||||
begin
|
begin
|
||||||
MoveCursorToNodeStart(ContextNode);
|
if (Src[Params.IdentifierStartPos]<>'[') then begin
|
||||||
ReadNextAtom; // read keyword 'property'
|
MoveCursorToNodeStart(ContextNode);
|
||||||
ReadNextAtom; // read name
|
ReadNextAtom; // read keyword 'property'
|
||||||
if CompareSrcIdentifiers(Params.IdentifierStartPos,CurPos.StartPos)
|
ReadNextAtom; // read name
|
||||||
then begin
|
if CompareSrcIdentifiers(Params.IdentifierStartPos,CurPos.StartPos)
|
||||||
// identifier found
|
then begin
|
||||||
Result:=true;
|
// identifier found
|
||||||
Params.SetResult(Self,ContextNode,CurPos.StartPos);
|
Result:=true;
|
||||||
exit;
|
Params.SetResult(Self,ContextNode,CurPos.StartPos);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
// the default property is searched
|
||||||
|
Result:=PropertyIsDefault(ContextNode);
|
||||||
|
if Result then exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -752,7 +766,8 @@ writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching in Parent Con
|
|||||||
ctnTypeSection, ctnVarSection, ctnConstSection, ctnResStrSection,
|
ctnTypeSection, ctnVarSection, ctnConstSection, ctnResStrSection,
|
||||||
ctnInterface, ctnImplementation,
|
ctnInterface, ctnImplementation,
|
||||||
ctnClassPublished,ctnClassPublic,ctnClassProtected, ctnClassPrivate,
|
ctnClassPublished,ctnClassPublic,ctnClassProtected, ctnClassPrivate,
|
||||||
ctnRecordCase, ctnRecordVariant:
|
ctnRecordCase, ctnRecordVariant,
|
||||||
|
ctnProcedureHead, ctnParameterList:
|
||||||
// these codetreenodes build a parent-child-relationship, but
|
// these codetreenodes build a parent-child-relationship, but
|
||||||
// for pascal it is only a range, hence after searching in the
|
// for pascal it is only a range, hence after searching in the
|
||||||
// childs of the last node, it must be searched next in the childs
|
// childs of the last node, it must be searched next in the childs
|
||||||
@ -900,12 +915,17 @@ begin
|
|||||||
ReadPriorAtom;
|
ReadPriorAtom;
|
||||||
CurAtom:=CurPos;
|
CurAtom:=CurPos;
|
||||||
CurAtomType:=GetCurrentAtomType;
|
CurAtomType:=GetCurrentAtomType;
|
||||||
if CurAtomType=atNone then begin
|
if CurAtomType in [atNone,atSpace,atINHERITED,atRoundBracketOpen,
|
||||||
|
atEdgedBracketOpen,atRoundBracketClose] then begin
|
||||||
// no special context found -> the context node is the deepest node at
|
// no special context found -> the context node is the deepest node at
|
||||||
// cursor, and this should already be in Params.ContextNode
|
// cursor, and this should already be in Params.ContextNode
|
||||||
Result:=Params.ContextNode;
|
Result:=Params.ContextNode;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
if (CurAtomType in [atRoundBracketClose,atEdgedBracketClose]) then begin
|
||||||
|
ReadBackTilBracketClose(true);
|
||||||
|
CurAtom.StartPos:=CurPos.StartPos;
|
||||||
|
end;
|
||||||
Result:=FindContextNodeAtCursor(Params);
|
Result:=FindContextNodeAtCursor(Params);
|
||||||
if Result=nil then exit;
|
if Result=nil then exit;
|
||||||
|
|
||||||
@ -934,20 +954,42 @@ writeln('');
|
|||||||
MoveCursorToCleanPos(NextAtom.StartPos);
|
MoveCursorToCleanPos(NextAtom.StartPos);
|
||||||
RaiseException('syntax error: "'+GetAtom+'" found');
|
RaiseException('syntax error: "'+GetAtom+'" found');
|
||||||
end;
|
end;
|
||||||
if (Result=Params.ContextNode)
|
if (Result=Params.ContextNode) then begin
|
||||||
and (CompareSrcIdentifier(CurAtom.StartPos,'SELF')) then begin
|
if CompareSrcIdentifier(CurAtom.StartPos,'SELF') then begin
|
||||||
// SELF in a method is the object itself
|
// SELF in a method is the object itself
|
||||||
// -> check if in a proc
|
// -> check if in a proc
|
||||||
ProcNode:=Params.ContextNode;
|
ProcNode:=Params.ContextNode;
|
||||||
while (ProcNode<>nil) do begin
|
while (ProcNode<>nil) do begin
|
||||||
if (ProcNode.Desc=ctnProcedure) then begin
|
if (ProcNode.Desc=ctnProcedure) then begin
|
||||||
// in a proc -> find the class context
|
// in a proc -> find the class context
|
||||||
if FindClassOfMethod(ProcNode,Params,true) then begin
|
if FindClassOfMethod(ProcNode,Params,true) then begin
|
||||||
Result:=Params.NewNode;
|
Result:=Params.NewNode;
|
||||||
exit;
|
exit;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
ProcNode:=ProcNode.Parent;
|
||||||
|
end;
|
||||||
|
end else if CompareSrcIdentifier(CurAtom.StartPos,'RESULT') then begin
|
||||||
|
// RESULT has a special meaning in a function
|
||||||
|
// -> check if in a function
|
||||||
|
ProcNode:=Params.ContextNode;
|
||||||
|
while (ProcNode<>nil) do begin
|
||||||
|
if (ProcNode.Desc=ctnProcedure) then begin
|
||||||
|
MoveCursorToNodeStart(ProcNode);
|
||||||
|
ReadNextAtom;
|
||||||
|
if UpAtomIs('CLASS') then ReadNextAtom;
|
||||||
|
if UpAtomIs('FUNCTION') then begin;
|
||||||
|
// in a function -> find the result type
|
||||||
|
BuildSubTreeForProcHead(ProcNode);
|
||||||
|
ProcNode:=ProcNode.FirstChild.FirstChild;
|
||||||
|
if Result.Desc=ctnParameterList then
|
||||||
|
Result:=Result.NextBrother;
|
||||||
|
FindBaseTypeOfNode(Params,Result);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
ProcNode:=ProcNode.Parent;
|
||||||
end;
|
end;
|
||||||
ProcNode:=ProcNode.Parent;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
// find identifier
|
// find identifier
|
||||||
@ -970,6 +1012,7 @@ writeln('');
|
|||||||
finally
|
finally
|
||||||
Params.Load(OldInput);
|
Params.Load(OldInput);
|
||||||
end;
|
end;
|
||||||
|
Result:=FindBaseTypeOfNode(Params,Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
atPoint:
|
atPoint:
|
||||||
@ -1013,17 +1056,56 @@ writeln('');
|
|||||||
MoveCursorToCleanPos(CurAtom.StartPos);
|
MoveCursorToCleanPos(CurAtom.StartPos);
|
||||||
RaiseException('illegal qualifier ^');
|
RaiseException('illegal qualifier ^');
|
||||||
end;
|
end;
|
||||||
Result:=Result.FirstChild;
|
Result:=FindBaseTypeOfNode(Params,Result.FirstChild);
|
||||||
end else if NodeHasParentOfType(Result,ctnPointerType) then begin
|
end else if NodeHasParentOfType(Result,ctnPointerType) then begin
|
||||||
// this is a pointer type definition
|
// this is a pointer type definition
|
||||||
// -> the default context is ok
|
// -> the default context is ok
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
atEdgedBracketClose:
|
||||||
|
begin
|
||||||
|
// for example: a[]
|
||||||
|
// this could be:
|
||||||
|
// 1. ranged array
|
||||||
|
// 2. dynamic array
|
||||||
|
// 3. indexed pointer
|
||||||
|
// 4. default property
|
||||||
|
if Result<>Params.ContextNode then begin
|
||||||
|
case Result.Desc of
|
||||||
|
|
||||||
|
ctnArrayType:
|
||||||
|
// the array type is the last child node
|
||||||
|
Result:=FindBaseTypeOfNode(Params,Result.LastChild);
|
||||||
|
|
||||||
// ToDo: atINHERITED, atRoundBracketClose, atEdgedBracketClose
|
ctnPointerType:
|
||||||
|
// the pointer type is the only child node
|
||||||
|
Result:=FindBaseTypeOfNode(Params,Result.FirstChild);
|
||||||
|
|
||||||
|
ctnClass:
|
||||||
|
begin
|
||||||
|
Params.Save(OldInput);
|
||||||
|
Params.Flags:=[fdfSearchInAncestors,fdfExceptionOnNotFound]
|
||||||
|
+fdfGlobals*Params.Flags;
|
||||||
|
Params.IdentifierStartPos:=CurAtom.StartPos;
|
||||||
|
Params.IdentifierEndPos:=CurAtom.StartPos+1;
|
||||||
|
Params.ContextNode:=Result;
|
||||||
|
FindIdentifierInContext(Params);
|
||||||
|
Result:=FindBaseTypeOfNode(Params,Params.NewNode);
|
||||||
|
Params.Load(OldInput);
|
||||||
|
end;
|
||||||
|
|
||||||
|
else
|
||||||
|
MoveCursorToCleanPos(CurAtom.StartPos);
|
||||||
|
RaiseException('illegal qualifier');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// ToDo: atINHERITED, atRoundBracketClose
|
||||||
|
|
||||||
else
|
else
|
||||||
|
// expression start found
|
||||||
begin
|
begin
|
||||||
if (not (NextAtomType in [atSpace,atIdentifier,atRoundBracketOpen,
|
if (not (NextAtomType in [atSpace,atIdentifier,atRoundBracketOpen,
|
||||||
atEdgedBracketOpen])) then
|
atEdgedBracketOpen])) then
|
||||||
@ -1036,9 +1118,6 @@ writeln('');
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// try to get the base type of the found context
|
|
||||||
Result:=FindBaseTypeOfNode(Params,Result);
|
|
||||||
|
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
write('[TFindDeclarationTool.FindContextNodeAtCursor] END ',
|
write('[TFindDeclarationTool.FindContextNodeAtCursor] END ',
|
||||||
Params.ContextNode.DescAsString,' CurAtom=',AtomTypeNames[CurAtomType],
|
Params.ContextNode.DescAsString,' CurAtom=',AtomTypeNames[CurAtomType],
|
||||||
@ -1088,11 +1167,6 @@ begin
|
|||||||
Params.Load(OldInput);
|
Params.Load(OldInput);
|
||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
if (Result.Desc=ctnTypeType) then begin
|
|
||||||
// a TypeType is for example 'MyInt = type integer;'
|
|
||||||
// the context is not the 'type' keyword, but the identifier after it.
|
|
||||||
Result:=Result.FirstChild;
|
|
||||||
end else
|
|
||||||
if (Result.Desc=ctnIdentifier) then begin
|
if (Result.Desc=ctnIdentifier) then begin
|
||||||
// this type is just an alias for another type
|
// this type is just an alias for another type
|
||||||
// -> search the basic type
|
// -> search the basic type
|
||||||
@ -1113,6 +1187,30 @@ begin
|
|||||||
finally
|
finally
|
||||||
Params.Load(OldInput);
|
Params.Load(OldInput);
|
||||||
end;
|
end;
|
||||||
|
end else
|
||||||
|
if (Result.Desc=ctnProperty) then begin
|
||||||
|
// this is a property -> search the type definition of the property
|
||||||
|
ReadTilTypeOfProperty(Result);
|
||||||
|
Params.Save(OldInput);
|
||||||
|
try
|
||||||
|
Params.IdentifierStartPos:=CurPos.StartPos;
|
||||||
|
Params.IdentifierEndPos:=CurPos.EndPos;
|
||||||
|
Params.Flags:=[fdfSearchInParentNodes,fdfExceptionOnNotFound]
|
||||||
|
+(fdfGlobals*Params.Flags);
|
||||||
|
Params.ContextNode:=Result.Parent;
|
||||||
|
FindIdentifierInContext(Params);
|
||||||
|
if Result.HasAsParent(Params.NewNode) then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
Result:=Params.NewNode;
|
||||||
|
finally
|
||||||
|
Params.Load(OldInput);
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
if (Result.Desc=ctnTypeType) then begin
|
||||||
|
// a TypeType is for example 'MyInt = type integer;'
|
||||||
|
// the context is not the 'type' keyword, but the identifier after it.
|
||||||
|
Result:=Result.FirstChild;
|
||||||
end else
|
end else
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
@ -1139,6 +1237,8 @@ var
|
|||||||
ClassContextNode: TCodeTreeNode;
|
ClassContextNode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
|
// if proc is a method, search in class
|
||||||
|
// -> find class name
|
||||||
MoveCursorToNodeStart(ProcContextNode);
|
MoveCursorToNodeStart(ProcContextNode);
|
||||||
ReadNextAtom; // read keyword
|
ReadNextAtom; // read keyword
|
||||||
ReadNextAtom; // read classname
|
ReadNextAtom; // read classname
|
||||||
|
@ -76,7 +76,8 @@ type
|
|||||||
phpWithoutName, phpWithVarModifiers, phpWithParameterNames,
|
phpWithoutName, phpWithVarModifiers, phpWithParameterNames,
|
||||||
phpWithDefaultValues, phpWithResultType, phpWithComments, phpInUpperCase,
|
phpWithDefaultValues, phpWithResultType, phpWithComments, phpInUpperCase,
|
||||||
phpWithoutBrackets, phpIgnoreForwards, phpIgnoreProcsWithBody,
|
phpWithoutBrackets, phpIgnoreForwards, phpIgnoreProcsWithBody,
|
||||||
phpOnlyWithClassname, phpFindCleanPosition, phpWithoutParamList);
|
phpOnlyWithClassname, phpFindCleanPosition, phpWithoutParamList,
|
||||||
|
phpCreateNodes);
|
||||||
TProcHeadAttributes = set of TProcHeadAttribute;
|
TProcHeadAttributes = set of TProcHeadAttribute;
|
||||||
|
|
||||||
TProcHeadExtractPos = (phepNone, phepStart, phepName, phepParamList);
|
TProcHeadExtractPos = (phepNone, phepStart, phepName, phepParamList);
|
||||||
@ -143,7 +144,8 @@ type
|
|||||||
procedure BuildBlockStatementStartKeyWordFuncList; virtual;
|
procedure BuildBlockStatementStartKeyWordFuncList; virtual;
|
||||||
function UnexpectedKeyWord: boolean;
|
function UnexpectedKeyWord: boolean;
|
||||||
// read functions
|
// read functions
|
||||||
function ReadTilProcedureHeadEnd(IsMethod, IsFunction, IsType: boolean;
|
function ReadTilProcedureHeadEnd(IsMethod, IsFunction, IsType,
|
||||||
|
CreateNodes: boolean;
|
||||||
var HasForwardModifier: boolean): boolean;
|
var HasForwardModifier: boolean): boolean;
|
||||||
function ReadConstant(ExceptionOnError, Extract: boolean;
|
function ReadConstant(ExceptionOnError, Extract: boolean;
|
||||||
Attr: TProcHeadAttributes): boolean;
|
Attr: TProcHeadAttributes): boolean;
|
||||||
@ -162,6 +164,7 @@ type
|
|||||||
function ReadWithStatement(ExceptionOnError,
|
function ReadWithStatement(ExceptionOnError,
|
||||||
CreateNodes: boolean): boolean;
|
CreateNodes: boolean): boolean;
|
||||||
procedure ReadVariableType;
|
procedure ReadVariableType;
|
||||||
|
procedure ReadTilTypeOfProperty(PropertyNode: TCodeTreeNode);
|
||||||
public
|
public
|
||||||
CurSection: TCodeTreeNodeDesc;
|
CurSection: TCodeTreeNodeDesc;
|
||||||
|
|
||||||
@ -176,6 +179,7 @@ type
|
|||||||
CursorPos: TCodeXYPosition; var CleanCursorPos: integer);
|
CursorPos: TCodeXYPosition; var CleanCursorPos: integer);
|
||||||
procedure BuildSubTreeForClass(ClassNode: TCodeTreeNode); virtual;
|
procedure BuildSubTreeForClass(ClassNode: TCodeTreeNode); virtual;
|
||||||
procedure BuildSubTreeForBeginBlock(BeginNode: TCodeTreeNode); virtual;
|
procedure BuildSubTreeForBeginBlock(BeginNode: TCodeTreeNode); virtual;
|
||||||
|
procedure BuildSubTreeForProcHead(ProcNode: TCodeTreeNode); virtual;
|
||||||
function DoAtom: boolean; override;
|
function DoAtom: boolean; override;
|
||||||
function ExtractPropName(PropNode: TCodeTreeNode;
|
function ExtractPropName(PropNode: TCodeTreeNode;
|
||||||
InUpperCase: boolean): string;
|
InUpperCase: boolean): string;
|
||||||
@ -208,6 +212,7 @@ type
|
|||||||
function GetSourceType: TCodeTreeNodeDesc;
|
function GetSourceType: TCodeTreeNodeDesc;
|
||||||
function NodeHasParentOfType(ANode: TCodeTreeNode;
|
function NodeHasParentOfType(ANode: TCodeTreeNode;
|
||||||
NodeDesc: TCodeTreeNodeDesc): boolean;
|
NodeDesc: TCodeTreeNodeDesc): boolean;
|
||||||
|
function PropertyIsDefault(PropertyNode: TCodeTreeNode): boolean;
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
@ -851,7 +856,7 @@ begin
|
|||||||
IsFunction:=UpAtomIs('FUNCTION');
|
IsFunction:=UpAtomIs('FUNCTION');
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
HasForwardModifier:=false;
|
HasForwardModifier:=false;
|
||||||
ReadTilProcedureHeadEnd(true,IsFunction,true,HasForwardModifier);
|
ReadTilProcedureHeadEnd(true,IsFunction,true,false,HasForwardModifier);
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -930,7 +935,7 @@ begin
|
|||||||
CurNode.Desc:=ctnProcedureHead;
|
CurNode.Desc:=ctnProcedureHead;
|
||||||
// read rest
|
// read rest
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
ReadTilProcedureHeadEnd(true,IsFunction,false,HasForwardModifier);
|
ReadTilProcedureHeadEnd(true,IsFunction,false,false,HasForwardModifier);
|
||||||
// close procedure header
|
// close procedure header
|
||||||
CurNode.EndPos:=CurPos.EndPos;
|
CurNode.EndPos:=CurPos.EndPos;
|
||||||
EndChildNode;
|
EndChildNode;
|
||||||
@ -943,6 +948,7 @@ end;
|
|||||||
function TPascalParserTool.ReadParamList(ExceptionOnError, Extract: boolean;
|
function TPascalParserTool.ReadParamList(ExceptionOnError, Extract: boolean;
|
||||||
Attr: TProcHeadAttributes): boolean;
|
Attr: TProcHeadAttributes): boolean;
|
||||||
var CloseBracket: char;
|
var CloseBracket: char;
|
||||||
|
Desc: TCodeTreeNodeDesc;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
if AtomIsChar('(') or AtomIsChar('[') then begin
|
if AtomIsChar('(') or AtomIsChar('[') then begin
|
||||||
@ -950,6 +956,10 @@ begin
|
|||||||
CloseBracket:=')'
|
CloseBracket:=')'
|
||||||
else
|
else
|
||||||
CloseBracket:=']';
|
CloseBracket:=']';
|
||||||
|
if (phpCreateNodes in Attr) then begin
|
||||||
|
CreateChildNode;
|
||||||
|
CurNode.Desc:=ctnParameterList;
|
||||||
|
end;
|
||||||
if not Extract then
|
if not Extract then
|
||||||
ReadNextAtom
|
ReadNextAtom
|
||||||
else
|
else
|
||||||
@ -958,25 +968,37 @@ begin
|
|||||||
CloseBracket:=#0;
|
CloseBracket:=#0;
|
||||||
repeat
|
repeat
|
||||||
// read parameter prefix modifier
|
// read parameter prefix modifier
|
||||||
if (UpAtomIs('VAR')) or (UpAtomIs('CONST')) or (UpAtomIs('OUT')) then
|
if (UpAtomIs('VAR')) or (UpAtomIs('CONST')) or (UpAtomIs('OUT')) then begin
|
||||||
|
Desc:=ctnVarDefinition;
|
||||||
if not Extract then
|
if not Extract then
|
||||||
ReadNextAtom
|
ReadNextAtom
|
||||||
else
|
else
|
||||||
ExtractNextAtom(phpWithVarModifiers in Attr,Attr);
|
ExtractNextAtom(phpWithVarModifiers in Attr,Attr);
|
||||||
|
end else
|
||||||
|
Desc:=ctnVarDefinition;
|
||||||
// read parameter name(s)
|
// read parameter name(s)
|
||||||
repeat
|
repeat
|
||||||
AtomIsIdentifier(ExceptionOnError);
|
if not AtomIsIdentifier(ExceptionOnError) then exit;
|
||||||
|
if (phpCreateNodes in Attr) then begin
|
||||||
|
CreateChildNode;
|
||||||
|
CurNode.Desc:=Desc;
|
||||||
|
end;
|
||||||
if not Extract then
|
if not Extract then
|
||||||
ReadNextAtom
|
ReadNextAtom
|
||||||
else
|
else
|
||||||
ExtractNextAtom(phpWithParameterNames in Attr,Attr);
|
ExtractNextAtom(phpWithParameterNames in Attr,Attr);
|
||||||
if not AtomIsChar(',') then
|
if not AtomIsChar(',') then
|
||||||
break
|
break
|
||||||
else
|
else begin
|
||||||
|
if (phpCreateNodes in Attr) then begin
|
||||||
|
CurNode.EndPos:=LastAtoms.GetValueAt(0).EndPos;
|
||||||
|
EndChildNode;
|
||||||
|
end;
|
||||||
if not Extract then
|
if not Extract then
|
||||||
ReadNextAtom
|
ReadNextAtom
|
||||||
else
|
else
|
||||||
ExtractNextAtom(not (phpWithoutParamList in Attr),Attr);
|
ExtractNextAtom(not (phpWithoutParamList in Attr),Attr);
|
||||||
|
end;
|
||||||
until false;
|
until false;
|
||||||
// read type
|
// read type
|
||||||
if (AtomIsChar(':')) then begin
|
if (AtomIsChar(':')) then begin
|
||||||
@ -995,6 +1017,10 @@ begin
|
|||||||
Extract and (phpWithDefaultValues in Attr),Attr);
|
Extract and (phpWithDefaultValues in Attr),Attr);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
if (phpCreateNodes in Attr) then begin
|
||||||
|
CurNode.EndPos:=CurPos.EndPos;
|
||||||
|
EndChildNode;
|
||||||
|
end;
|
||||||
// read next parameter
|
// read next parameter
|
||||||
if (CurPos.StartPos>SrcLen) then
|
if (CurPos.StartPos>SrcLen) then
|
||||||
if ExceptionOnError then
|
if ExceptionOnError then
|
||||||
@ -1018,6 +1044,10 @@ begin
|
|||||||
RaiseException(
|
RaiseException(
|
||||||
'syntax error: '+CloseBracket+' expected, but '+GetAtom+' found')
|
'syntax error: '+CloseBracket+' expected, but '+GetAtom+' found')
|
||||||
else exit;
|
else exit;
|
||||||
|
if (phpCreateNodes in Attr) then begin
|
||||||
|
CurNode.EndPos:=CurPos.EndPos;
|
||||||
|
EndChildNode;
|
||||||
|
end;
|
||||||
if not Extract then
|
if not Extract then
|
||||||
ReadNextAtom
|
ReadNextAtom
|
||||||
else
|
else
|
||||||
@ -1032,6 +1062,10 @@ begin
|
|||||||
Result:=false;
|
Result:=false;
|
||||||
if AtomIsWord then begin
|
if AtomIsWord then begin
|
||||||
if UpAtomIs('ARRAY') then begin
|
if UpAtomIs('ARRAY') then begin
|
||||||
|
if (phpCreateNodes in Attr) then begin
|
||||||
|
CreateChildNode;
|
||||||
|
CurNode.Desc:=ctnArrayType;
|
||||||
|
end;
|
||||||
if not Extract then ReadNextAtom else ExtractNextAtom(true,Attr);
|
if not Extract then ReadNextAtom else ExtractNextAtom(true,Attr);
|
||||||
if not UpAtomIs('OF') then
|
if not UpAtomIs('OF') then
|
||||||
if ExceptionOnError then
|
if ExceptionOnError then
|
||||||
@ -1039,6 +1073,12 @@ begin
|
|||||||
else exit;
|
else exit;
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
if UpAtomIs('CONST') then begin
|
if UpAtomIs('CONST') then begin
|
||||||
|
if (phpCreateNodes in Attr) then begin
|
||||||
|
CreateChildNode;
|
||||||
|
CurNode.Desc:=ctnArrayType;
|
||||||
|
CurNode.EndPos:=CurPos.EndPos;
|
||||||
|
EndChildNode;
|
||||||
|
end;
|
||||||
if not Extract then
|
if not Extract then
|
||||||
ReadNextAtom
|
ReadNextAtom
|
||||||
else
|
else
|
||||||
@ -1048,6 +1088,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if not AtomIsIdentifier(ExceptionOnError) then exit;
|
if not AtomIsIdentifier(ExceptionOnError) then exit;
|
||||||
|
if (phpCreateNodes in Attr) then begin
|
||||||
|
CreateChildNode;
|
||||||
|
CurNode.Desc:=ctnIdentifier;
|
||||||
|
CurNode.EndPos:=CurPos.EndPos;
|
||||||
|
EndChildNode;
|
||||||
|
end;
|
||||||
if not Extract then
|
if not Extract then
|
||||||
ReadNextAtom
|
ReadNextAtom
|
||||||
else
|
else
|
||||||
@ -1062,7 +1108,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TPascalParserTool.ReadTilProcedureHeadEnd(
|
function TPascalParserTool.ReadTilProcedureHeadEnd(
|
||||||
IsMethod, IsFunction, IsType: boolean;
|
IsMethod, IsFunction, IsType, CreateNodes: boolean;
|
||||||
var HasForwardModifier: boolean): boolean;
|
var HasForwardModifier: boolean): boolean;
|
||||||
{ parse parameter list, result type, of object, method specifiers
|
{ parse parameter list, result type, of object, method specifiers
|
||||||
|
|
||||||
@ -1087,23 +1133,30 @@ function TPascalParserTool.ReadTilProcedureHeadEnd(
|
|||||||
[alias: <string constant>]
|
[alias: <string constant>]
|
||||||
}
|
}
|
||||||
var IsSpecifier: boolean;
|
var IsSpecifier: boolean;
|
||||||
|
Attr: TProcHeadAttributes;
|
||||||
begin
|
begin
|
||||||
//writeln('[TPascalParserTool.ReadTilProcedureHeadEnd] ',
|
//writeln('[TPascalParserTool.ReadTilProcedureHeadEnd] ',
|
||||||
//'Method=',IsMethod,', Function=',IsFunction,', Type=',IsType);
|
//'Method=',IsMethod,', Function=',IsFunction,', Type=',IsType);
|
||||||
Result:=true;
|
Result:=true;
|
||||||
HasForwardModifier:=false;
|
HasForwardModifier:=false;
|
||||||
if AtomIsChar('(') then
|
if AtomIsChar('(') then begin
|
||||||
ReadParamList(true,false,[]);
|
Attr:=[];
|
||||||
|
if CreateNodes then
|
||||||
|
Include(Attr,phpCreateNodes);
|
||||||
|
ReadParamList(true,false,Attr);
|
||||||
|
end;
|
||||||
if IsFunction then begin
|
if IsFunction then begin
|
||||||
// read function result type
|
// read function result type
|
||||||
if not AtomIsChar(':') then
|
if not AtomIsChar(':') then
|
||||||
RaiseException('syntax error: : expected, but '+GetAtom+' found');
|
RaiseException('syntax error: : expected, but '+GetAtom+' found');
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
if (CurPos.StartPos>SrcLen)
|
AtomIsIdentifier(true);
|
||||||
or (not (UpperSrc[CurPos.StartPos] in ['A'..'Z','_']))
|
if CreateNodes then begin
|
||||||
then
|
CreateChildNode;
|
||||||
RaiseException(
|
CurNode.Desc:=ctnIdentifier;
|
||||||
'syntax error: method result type expected but '+GetAtom+' found');
|
CurNode.EndPos:=CurPos.EndPos;
|
||||||
|
EndChildNode;
|
||||||
|
end;
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
end;
|
end;
|
||||||
if UpAtomIs('OF') then begin
|
if UpAtomIs('OF') then begin
|
||||||
@ -1537,7 +1590,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
// read rest of procedure head
|
// read rest of procedure head
|
||||||
HasForwardModifier:=false;
|
HasForwardModifier:=false;
|
||||||
ReadTilProcedureHeadEnd(false,IsFunction,false,HasForwardModifier);
|
ReadTilProcedureHeadEnd(false,IsFunction,false,false,HasForwardModifier);
|
||||||
if ChildCreated then begin
|
if ChildCreated then begin
|
||||||
if HasForwardModifier then
|
if HasForwardModifier then
|
||||||
ProcNode.SubDesc:=ctnsForwardDeclaration;
|
ProcNode.SubDesc:=ctnsForwardDeclaration;
|
||||||
@ -3059,6 +3112,67 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPascalParserTool.ReadTilTypeOfProperty(PropertyNode: TCodeTreeNode);
|
||||||
|
begin
|
||||||
|
MoveCursorToNodeStart(PropertyNode);
|
||||||
|
ReadNextAtom; // read keyword 'property'
|
||||||
|
ReadNextAtom; // read property name
|
||||||
|
AtomIsIdentifier(true);
|
||||||
|
ReadNextAtom;
|
||||||
|
if AtomIsChar('[') then begin
|
||||||
|
// read parameter list
|
||||||
|
ReadTilBracketClose(true);
|
||||||
|
ReadNextAtom;
|
||||||
|
end;
|
||||||
|
if not AtomIsChar(':') then
|
||||||
|
RaiseException('syntax error: : expected, but '+GetAtom+' found');
|
||||||
|
ReadNextAtom; // read type
|
||||||
|
AtomIsIdentifier(true);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPascalParserTool.PropertyIsDefault(PropertyNode: TCodeTreeNode
|
||||||
|
): boolean;
|
||||||
|
begin
|
||||||
|
Result:=false;
|
||||||
|
if (PropertyNode=nil) or (PropertyNode.Desc<>ctnProperty) then exit;
|
||||||
|
MoveCursorToCleanPos(PropertyNode.EndPos);
|
||||||
|
ReadPriorAtom;
|
||||||
|
if (not AtomIsChar(';')) then exit;
|
||||||
|
ReadPriorAtom;
|
||||||
|
Result:=UpAtomIs('DEFAULT');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPascalParserTool.BuildSubTreeForProcHead(ProcNode: TCodeTreeNode);
|
||||||
|
var HasForwardModifier, IsFunction: boolean;
|
||||||
|
begin
|
||||||
|
if ProcNode.Desc=ctnProcedureHead then ProcNode:=ProcNode.Parent;
|
||||||
|
if (ProcNode=nil) or (ProcNode.Desc<>ctnProcedure)
|
||||||
|
or (ProcNode.FirstChild=nil) then
|
||||||
|
RaiseException('[TPascalParserTool.BuildSubTreeForProcHead] '
|
||||||
|
+'internal error: invalid ProcNode');
|
||||||
|
if ProcNode.FirstChild.SubDesc=ctnsProcHeadNodesCreated then exit;
|
||||||
|
MoveCursorToNodeStart(ProcNode);
|
||||||
|
ReadNextAtom;
|
||||||
|
if UpAtomIs('CLASS') then
|
||||||
|
ReadNextAtom;
|
||||||
|
IsFunction:=UpAtomIs('FUNCTION');
|
||||||
|
// read procedure head (= name + parameterlist + resulttype;)
|
||||||
|
CurNode:=ProcNode.FirstChild;
|
||||||
|
ReadNextAtom;// read first atom of head
|
||||||
|
AtomIsIdentifier(true);
|
||||||
|
ReadNextAtom;
|
||||||
|
if AtomIsChar('.') then begin
|
||||||
|
// read procedure name of a class method (the name after the . )
|
||||||
|
ReadNextAtom;
|
||||||
|
AtomIsIdentifier(true);
|
||||||
|
ReadNextAtom;
|
||||||
|
end;
|
||||||
|
// read rest of procedure head and build nodes
|
||||||
|
HasForwardModifier:=false;
|
||||||
|
ReadTilProcedureHeadEnd(false,IsFunction,false,true,HasForwardModifier);
|
||||||
|
ProcNode.FirstChild.SubDesc:=ctnsProcHeadNodesCreated;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user