mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-19 04:49:41 +01:00
codetools: parsing advanced records
git-svn-id: trunk@29359 -
This commit is contained in:
parent
0324c50205
commit
05be735961
@ -4615,7 +4615,7 @@ function TCodeCompletionCodeTool.BuildUnitDefinitionGraph(out
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ctnRecordType, ctnClassInterface, ctnDispinterface, ctnClass, ctnObject,
|
ctnClassInterface, ctnDispinterface, ctnClass, ctnObject, ctnRecordType,
|
||||||
ctnObjCClass, ctnObjCCategory, ctnObjCProtocol, ctnCPPClass:
|
ctnObjCClass, ctnObjCCategory, ctnObjCProtocol, ctnCPPClass:
|
||||||
begin
|
begin
|
||||||
ChildNode:=SubNode.FirstChild;
|
ChildNode:=SubNode.FirstChild;
|
||||||
|
|||||||
@ -158,12 +158,10 @@ const
|
|||||||
[ctnClassPublic,ctnClassPublished,ctnClassPrivate,ctnClassProtected];
|
[ctnClassPublic,ctnClassPublished,ctnClassPrivate,ctnClassProtected];
|
||||||
AllClassSections =
|
AllClassSections =
|
||||||
AllClassBaseSections+[ctnClassConst, ctnClassType, ctnClassVar, ctnClassClassVar];
|
AllClassBaseSections+[ctnClassConst, ctnClassType, ctnClassVar, ctnClassClassVar];
|
||||||
AllClasses =
|
|
||||||
[ctnClass,ctnClassInterface,ctnDispinterface,ctnObject,
|
|
||||||
ctnObjCClass,ctnObjCCategory,ctnObjCProtocol,
|
|
||||||
ctnCPPClass];
|
|
||||||
AllClassInterfaces = [ctnClassInterface,ctnDispinterface,ctnObjCProtocol];
|
AllClassInterfaces = [ctnClassInterface,ctnDispinterface,ctnObjCProtocol];
|
||||||
AllClassObjects = [ctnClass,ctnObject,ctnObjCClass,ctnObjCCategory,ctnCPPClass];
|
AllClassObjects = [ctnClass,ctnObject,ctnRecordType,
|
||||||
|
ctnObjCClass,ctnObjCCategory,ctnCPPClass];
|
||||||
|
AllClasses = AllClassObjects+AllClassObjects;
|
||||||
AllClassModifiers = [ctnClassAbstract, ctnClassSealed, ctnClassExternal];
|
AllClassModifiers = [ctnClassAbstract, ctnClassSealed, ctnClassExternal];
|
||||||
AllDefinitionSections =
|
AllDefinitionSections =
|
||||||
[ctnTypeSection,ctnVarSection,ctnConstSection,ctnResStrSection,
|
[ctnTypeSection,ctnVarSection,ctnConstSection,ctnResStrSection,
|
||||||
@ -175,7 +173,7 @@ const
|
|||||||
AllPascalTypes =
|
AllPascalTypes =
|
||||||
AllClasses+
|
AllClasses+
|
||||||
[ctnGenericType,ctnSpecialize,
|
[ctnGenericType,ctnSpecialize,
|
||||||
ctnIdentifier,ctnOpenArrayType,ctnRangedArrayType,ctnRecordType,
|
ctnIdentifier,ctnOpenArrayType,ctnRangedArrayType,
|
||||||
ctnRecordCase,ctnRecordVariant,
|
ctnRecordCase,ctnRecordVariant,
|
||||||
ctnProcedureType,ctnSetType,ctnRangeType,ctnEnumerationType,
|
ctnProcedureType,ctnSetType,ctnRangeType,ctnEnumerationType,
|
||||||
ctnEnumIdentifier,ctnLabelType,ctnTypeType,ctnFileType,ctnPointerType,
|
ctnEnumIdentifier,ctnLabelType,ctnTypeType,ctnFileType,ctnPointerType,
|
||||||
@ -184,8 +182,7 @@ const
|
|||||||
ctnOnBlock,ctnOnIdentifier,ctnOnStatement];
|
ctnOnBlock,ctnOnIdentifier,ctnOnStatement];
|
||||||
AllFindContextDescs = AllIdentifierDefinitions + AllCodeSections + AllClasses +
|
AllFindContextDescs = AllIdentifierDefinitions + AllCodeSections + AllClasses +
|
||||||
[ctnProcedure];
|
[ctnProcedure];
|
||||||
AllPointContexts = AllClasses+AllSourceTypes+[ctnRecordType,
|
AllPointContexts = AllClasses+AllSourceTypes+[ctnEnumerationType,ctnInterface];
|
||||||
ctnEnumerationType,ctnInterface];
|
|
||||||
|
|
||||||
|
|
||||||
// CodeTreeNodeSubDescriptors
|
// CodeTreeNodeSubDescriptors
|
||||||
|
|||||||
@ -582,7 +582,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
if (SubDesc and ctnsNeedJITParsing)>0 then Result:=ctsUnparsed;
|
if (SubDesc and ctnsNeedJITParsing)>0 then Result:=ctsUnparsed;
|
||||||
end;
|
end;
|
||||||
ctnClass,ctnObject,ctnObjCClass,ctnObjCCategory,ctnObjCProtocol,
|
ctnClass,ctnObject,ctnRecordType,ctnObjCClass,ctnObjCCategory,ctnObjCProtocol,
|
||||||
ctnCPPClass,ctnClassInterface,ctnDispinterface:
|
ctnCPPClass,ctnClassInterface,ctnDispinterface:
|
||||||
begin
|
begin
|
||||||
Result:='';
|
Result:='';
|
||||||
|
|||||||
@ -3,15 +3,18 @@ program RecordsExample;
|
|||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
{$modeswitch advancedrecords} // {$mode delphi} has it automatically
|
{$modeswitch advancedrecords} // {$mode delphi} has it automatically
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils;
|
||||||
|
|
||||||
// advanced records
|
// advanced records
|
||||||
type
|
type
|
||||||
TRec1 = record
|
TRec1 = record
|
||||||
hWnd : HWND;
|
hWnd : integer;
|
||||||
private
|
private
|
||||||
F1: Integer;
|
F1: Integer;
|
||||||
F2: Byte;
|
F2: Byte;
|
||||||
public
|
public
|
||||||
type
|
{ type
|
||||||
TBar = Integer;
|
TBar = Integer;
|
||||||
const
|
const
|
||||||
C: TBar = 1;
|
C: TBar = 1;
|
||||||
@ -26,30 +29,42 @@ type
|
|||||||
var
|
var
|
||||||
F: Int;
|
F: Int;
|
||||||
const
|
const
|
||||||
DefaultF: Int = 1;
|
DefaultF: Int = 1;}
|
||||||
public
|
public
|
||||||
function GetF: Int;
|
function GetF: integer;
|
||||||
procedure SetF(const Value: Int);
|
procedure SetF(const Value: integer);
|
||||||
// full list of operators see in tests/test/terecs6.pp
|
// full list of operators see in tests/test/terecs6.pp
|
||||||
class operator Inc(Rec: TRec1): TRec1;
|
class operator Inc(Rec: TRec1): TRec1;
|
||||||
|
public
|
||||||
|
case y: integer of
|
||||||
|
0: (a: integer);
|
||||||
|
1,2,3: (b: array[char] of char; c: char);
|
||||||
|
3: ( d: record
|
||||||
|
case byte of
|
||||||
|
10: (i: integer; );
|
||||||
|
11: (y: byte);
|
||||||
|
end; );
|
||||||
|
4: (e: integer;
|
||||||
|
case byte of
|
||||||
|
8: (f: integer)
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TRec1.GetF: Int;
|
function TRec1.GetF: integer;
|
||||||
begin
|
begin
|
||||||
Result := F;
|
Result := F1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TRec1.SetF(const Value: Int);
|
procedure TRec1.SetF(const Value: integer);
|
||||||
begin
|
begin
|
||||||
F := Value;
|
F1 := Value;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class operator TRec1.Inc(Rec: TRec1): TRec1;
|
class operator TRec1.Inc(Rec: TRec1): TRec1;
|
||||||
begin
|
begin
|
||||||
Result.F := Rec.F + 1;
|
Result.F1 := Rec.F1 + 1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|||||||
@ -108,7 +108,7 @@ type
|
|||||||
}
|
}
|
||||||
const
|
const
|
||||||
AllNodeCacheDescs =
|
AllNodeCacheDescs =
|
||||||
AllClasses+[ctnProcedure, ctnRecordType, ctnWithStatement];
|
AllClasses+[ctnProcedure, ctnWithStatement];
|
||||||
|
|
||||||
type
|
type
|
||||||
TNodeCacheEntryFlag = (ncefSearchedInParents, ncefSearchedInAncestors);
|
TNodeCacheEntryFlag = (ncefSearchedInParents, ncefSearchedInAncestors);
|
||||||
|
|||||||
@ -1681,8 +1681,7 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if (not (Context.Node.Desc in (AllClasses+[ctnRecordType])))
|
if (not (Context.Node.Desc in AllClasses)) then begin
|
||||||
then begin
|
|
||||||
debugln(['TFindDeclarationTool.FindDeclarationOfPropertyPath failed Context=',Context.Node.DescAsString]);
|
debugln(['TFindDeclarationTool.FindDeclarationOfPropertyPath failed Context=',Context.Node.DescAsString]);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -2189,7 +2188,8 @@ begin
|
|||||||
TypeNode:=NewTool.FindTypeNodeOfDefinition(NewNode);
|
TypeNode:=NewTool.FindTypeNodeOfDefinition(NewNode);
|
||||||
if TypeNode<>nil then begin
|
if TypeNode<>nil then begin
|
||||||
case TypeNode.Desc of
|
case TypeNode.Desc of
|
||||||
ctnIdentifier, ctnClass, ctnClassInterface, ctnDispinterface, ctnObject,
|
ctnIdentifier, ctnClass, ctnClassInterface, ctnDispinterface,
|
||||||
|
ctnObject, ctnRecordType,
|
||||||
ctnObjCClass, ctnObjCCategory, ctnObjCProtocol, ctnCPPClass:
|
ctnObjCClass, ctnObjCCategory, ctnObjCProtocol, ctnCPPClass:
|
||||||
begin
|
begin
|
||||||
NewTool.MoveCursorToNodeStart(TypeNode);
|
NewTool.MoveCursorToNodeStart(TypeNode);
|
||||||
@ -2309,7 +2309,7 @@ begin
|
|||||||
Params.Flags:=Params.Flags+[fdfFunctionResult,fdfFindChilds];
|
Params.Flags:=Params.Flags+[fdfFunctionResult,fdfFindChilds];
|
||||||
FindContext:=FindBaseTypeOfNode(Params,ANode);
|
FindContext:=FindBaseTypeOfNode(Params,ANode);
|
||||||
if (FindContext.Node<>nil)
|
if (FindContext.Node<>nil)
|
||||||
and ((FindContext.Node.Desc in ([ctnRecordType,ctnEnumerationType]+AllClasses)))
|
and ((FindContext.Node.Desc in ([ctnEnumerationType]+AllClasses)))
|
||||||
and (FindContext.Node.FirstChild<>nil)
|
and (FindContext.Node.FirstChild<>nil)
|
||||||
then
|
then
|
||||||
Result:=true;
|
Result:=true;
|
||||||
@ -4568,10 +4568,6 @@ begin
|
|||||||
Result:=InNodeIdentifier(CurPos.StartPos);
|
Result:=InNodeIdentifier(CurPos.StartPos);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ctnBeginBlock,ctnClass,ctnObject,ctnObjCClass,ctnObjCCategory,ctnCPPClass:
|
|
||||||
if (Node.SubDesc and ctnsForwardDeclaration)>0 then
|
|
||||||
RaiseException('TFindDeclarationTool.CleanPosIsDeclarationIdentifier Node not expanded');
|
|
||||||
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -5199,7 +5195,7 @@ begin
|
|||||||
or (WithVarExpr.Context.Node=nil)
|
or (WithVarExpr.Context.Node=nil)
|
||||||
or (WithVarExpr.Context.Node=OldInput.ContextNode)
|
or (WithVarExpr.Context.Node=OldInput.ContextNode)
|
||||||
or (not (WithVarExpr.Context.Node.Desc
|
or (not (WithVarExpr.Context.Node.Desc
|
||||||
in (AllClasses+[ctnRecordType,ctnEnumerationType])))
|
in (AllClasses+[ctnEnumerationType])))
|
||||||
then begin
|
then begin
|
||||||
MoveCursorToCleanPos(WithVarNode.StartPos);
|
MoveCursorToCleanPos(WithVarNode.StartPos);
|
||||||
RaiseException(ctsExprTypeMustBeClassOrRecord);
|
RaiseException(ctsExprTypeMustBeClassOrRecord);
|
||||||
@ -6839,7 +6835,7 @@ var
|
|||||||
ExprType.Context:=ExprType.Context.Tool.FindBaseTypeOfNode(Params,
|
ExprType.Context:=ExprType.Context.Tool.FindBaseTypeOfNode(Params,
|
||||||
ExprType.Context.Node.FirstChild);
|
ExprType.Context.Node.FirstChild);
|
||||||
|
|
||||||
ctnClass, ctnClassInterface, ctnDispinterface, ctnObject,
|
ctnClass, ctnClassInterface, ctnDispinterface, ctnObject, ctnRecordType,
|
||||||
ctnObjCClass, ctnObjCCategory, ctnObjCProtocol, ctnCPPClass,
|
ctnObjCClass, ctnObjCCategory, ctnObjCProtocol, ctnCPPClass,
|
||||||
ctnProperty, ctnGlobalProperty:
|
ctnProperty, ctnGlobalProperty:
|
||||||
begin
|
begin
|
||||||
@ -8384,7 +8380,7 @@ begin
|
|||||||
// same context type
|
// same context type
|
||||||
case ExprNode.Desc of
|
case ExprNode.Desc of
|
||||||
|
|
||||||
ctnClass, ctnClassInterface, ctnDispinterface, ctnObject,
|
ctnClass, ctnClassInterface, ctnDispinterface, ctnObject, ctnRecordType,
|
||||||
ctnObjCClass, ctnObjCCategory, ctnObjCProtocol, ctnCPPClass:
|
ctnObjCClass, ctnObjCCategory, ctnObjCProtocol, ctnCPPClass:
|
||||||
// check, if ExpressionType.Context is descend of TargetContext
|
// check, if ExpressionType.Context is descend of TargetContext
|
||||||
if ContextIsDescendOf(ExpressionType.Context,
|
if ContextIsDescendOf(ExpressionType.Context,
|
||||||
@ -9530,7 +9526,7 @@ begin
|
|||||||
DebugLn(['TFindDeclarationTool.FindOperatorEnumerator ClassContext=',FindContextToString(ClassContext)]);
|
DebugLn(['TFindDeclarationTool.FindOperatorEnumerator ClassContext=',FindContextToString(ClassContext)]);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
case ClassContext.Node.Desc of
|
case ClassContext.Node.Desc of
|
||||||
ctnClass,ctnObject,ctnClassInterface: ;
|
ctnClass,ctnObject,ctnRecordType,ctnClassInterface: ;
|
||||||
else
|
else
|
||||||
OperatorTool.MoveCursorToNodeStart(OperatorNode);
|
OperatorTool.MoveCursorToNodeStart(OperatorNode);
|
||||||
OperatorTool.RaiseException('operator enumerator result type is not object');
|
OperatorTool.RaiseException('operator enumerator result type is not object');
|
||||||
@ -9940,7 +9936,7 @@ begin
|
|||||||
Result:=GetIdentifier(@FindContext.Tool.Src[ANode.StartPos]);
|
Result:=GetIdentifier(@FindContext.Tool.Src[ANode.StartPos]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ctnClass, ctnClassInterface, ctnDispinterface, ctnObject,
|
ctnClass, ctnClassInterface, ctnDispinterface, ctnObject, ctnRecordType,
|
||||||
ctnObjCClass, ctnObjCCategory, ctnObjCProtocol, ctnCPPClass:
|
ctnObjCClass, ctnObjCCategory, ctnObjCProtocol, ctnCPPClass:
|
||||||
if (FindContext.Node.Parent<>nil)
|
if (FindContext.Node.Parent<>nil)
|
||||||
and (FindContext.Node.Parent.Desc in [ctnTypeDefinition,ctnGenericType])
|
and (FindContext.Node.Parent.Desc in [ctnTypeDefinition,ctnGenericType])
|
||||||
|
|||||||
@ -161,7 +161,7 @@ begin
|
|||||||
while ParentCodeNode<>nil do begin
|
while ParentCodeNode<>nil do begin
|
||||||
//DebugLn(['TDeclarationOverloadsGraph.AddContext ',ParentCodeNode.DescAsString]);
|
//DebugLn(['TDeclarationOverloadsGraph.AddContext ',ParentCodeNode.DescAsString]);
|
||||||
if ParentCodeNode.Desc in
|
if ParentCodeNode.Desc in
|
||||||
AllSourceTypes+AllClasses+[ctnRecordType]
|
AllSourceTypes+AllClasses
|
||||||
then begin
|
then begin
|
||||||
//DebugLn(['TDeclarationOverloadsGraph.AddContext ADD parent']);
|
//DebugLn(['TDeclarationOverloadsGraph.AddContext ADD parent']);
|
||||||
ParentGraphNode:=AddContext(Tool,ParentCodeNode);
|
ParentGraphNode:=AddContext(Tool,ParentCodeNode);
|
||||||
|
|||||||
@ -1598,8 +1598,9 @@ var
|
|||||||
begin
|
begin
|
||||||
Node:=Context.Node;
|
Node:=Context.Node;
|
||||||
//debugln(['TIdentCompletionTool.GatherContextKeywords ',Node.DescAsString]);
|
//debugln(['TIdentCompletionTool.GatherContextKeywords ',Node.DescAsString]);
|
||||||
|
|
||||||
case Node.Desc of
|
case Node.Desc of
|
||||||
ctnClass,ctnObject,ctnObjCCategory,ctnObjCClass,
|
ctnClass,ctnObject,ctnRecordType,ctnObjCCategory,ctnObjCClass,
|
||||||
ctnClassPrivate,ctnClassProtected,ctnClassPublic,ctnClassPublished:
|
ctnClassPrivate,ctnClassProtected,ctnClassPublic,ctnClassPublished:
|
||||||
begin
|
begin
|
||||||
Add('public');
|
Add('public');
|
||||||
@ -1609,8 +1610,13 @@ begin
|
|||||||
Add('procedure');
|
Add('procedure');
|
||||||
Add('function');
|
Add('function');
|
||||||
Add('property');
|
Add('property');
|
||||||
Add('constructor');
|
if (Node.Desc=ctnClass) or (Node.Parent.Desc=ctnClass) then begin
|
||||||
Add('destructor');
|
Add('constructor');
|
||||||
|
Add('destructor');
|
||||||
|
end;
|
||||||
|
if (Node.Desc=ctnRecordType) or (Node.Parent.Desc=ctnRecordType) then begin
|
||||||
|
Add('case');
|
||||||
|
end;
|
||||||
if (Node.LastChild<>nil) and (CleanPos>Node.LastChild.StartPos)
|
if (Node.LastChild<>nil) and (CleanPos>Node.LastChild.StartPos)
|
||||||
and (Node.LastChild.EndPos>Node.LastChild.StartPos)
|
and (Node.LastChild.EndPos>Node.LastChild.StartPos)
|
||||||
and (Node.LastChild.EndPos<Srclen) then begin
|
and (Node.LastChild.EndPos<Srclen) then begin
|
||||||
@ -1656,7 +1662,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
ctnVarDefinition:
|
ctnVarDefinition:
|
||||||
if Node.Parent.Desc in [ctnClass,ctnObject,ctnObjCCategory,ctnObjCClass]
|
if Node.Parent.Desc in [ctnClass,ctnObject,ctnRecordType,ctnObjCCategory,ctnObjCClass]
|
||||||
+AllClassBaseSections
|
+AllClassBaseSections
|
||||||
then begin
|
then begin
|
||||||
Add('public');
|
Add('public');
|
||||||
@ -1666,8 +1672,13 @@ begin
|
|||||||
Add('procedure');
|
Add('procedure');
|
||||||
Add('function');
|
Add('function');
|
||||||
Add('property');
|
Add('property');
|
||||||
Add('constructor');
|
if (Node.Desc=ctnClass) or (Node.Parent.Desc=ctnClass) then begin
|
||||||
Add('destructor');
|
Add('constructor');
|
||||||
|
Add('destructor');
|
||||||
|
end;
|
||||||
|
if (Node.Desc=ctnRecordType) or (Node.Parent.Desc=ctnRecordType) then begin
|
||||||
|
Add('case');
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ctnProperty:
|
ctnProperty:
|
||||||
@ -2789,7 +2800,7 @@ var
|
|||||||
ANode: TCodeTreeNode;
|
ANode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
if GetDesc in (AllClasses+[ctnRecordType]) then begin
|
if GetDesc in AllClasses then begin
|
||||||
Result:=true;
|
Result:=true;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -2798,7 +2809,7 @@ begin
|
|||||||
UpdateBaseContext;
|
UpdateBaseContext;
|
||||||
if (BaseExprType.Desc=xtContext)
|
if (BaseExprType.Desc=xtContext)
|
||||||
and (BaseExprType.Context.Node<>nil)
|
and (BaseExprType.Context.Node<>nil)
|
||||||
and (BaseExprType.Context.Node.Desc in (AllClasses+[ctnRecordType]))
|
and (BaseExprType.Context.Node.Desc in AllClasses)
|
||||||
then
|
then
|
||||||
Include(Flags,iliHasChilds);
|
Include(Flags,iliHasChilds);
|
||||||
Result:=true;
|
Result:=true;
|
||||||
|
|||||||
@ -350,7 +350,8 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
// first test if in a class
|
// first test if in a class
|
||||||
ClassNode:=CursorNode.GetNodeOfTypes([ctnClass,ctnClassInterface,
|
ClassNode:=CursorNode.GetNodeOfTypes([ctnClass,ctnClassInterface,
|
||||||
ctnDispinterface,ctnObject,ctnObjCClass,ctnObjCCategory,ctnObjCProtocol,
|
ctnDispinterface,ctnObject,ctnRecordType,
|
||||||
|
ctnObjCClass,ctnObjCCategory,ctnObjCProtocol,
|
||||||
ctnCPPClass]);
|
ctnCPPClass]);
|
||||||
if ClassNode<>nil then begin
|
if ClassNode<>nil then begin
|
||||||
// cursor is in class/object/interface definition
|
// cursor is in class/object/interface definition
|
||||||
@ -792,7 +793,7 @@ begin
|
|||||||
cmp:=false;
|
cmp:=false;
|
||||||
end;
|
end;
|
||||||
if cmp and (phpIgnoreMethods in Attr) then begin
|
if cmp and (phpIgnoreMethods in Attr) then begin
|
||||||
if (ANode.GetNodeOfTypes([ctnClass,ctnObject,
|
if (ANode.GetNodeOfTypes([ctnClass,ctnObject,ctnRecordType,
|
||||||
ctnObjCClass,ctnObjCCategory,ctnCPPClass])<>nil)
|
ctnObjCClass,ctnObjCCategory,ctnCPPClass])<>nil)
|
||||||
or (ExtractClassNameOfProcNode(ANode)<>'')
|
or (ExtractClassNameOfProcNode(ANode)<>'')
|
||||||
then
|
then
|
||||||
|
|||||||
@ -141,8 +141,8 @@ type
|
|||||||
procedure ReadConst;
|
procedure ReadConst;
|
||||||
// types
|
// types
|
||||||
procedure ReadEqualsType;
|
procedure ReadEqualsType;
|
||||||
function KeyWordFuncClass: boolean;
|
function KeyWordFuncTypeClass: boolean;
|
||||||
function KeyWordFuncClassInterface: boolean;
|
function KeyWordFuncTypeClassInterface: boolean;
|
||||||
function KeyWordFuncTypePacked: boolean;
|
function KeyWordFuncTypePacked: boolean;
|
||||||
function KeyWordFuncTypeBitPacked: boolean;
|
function KeyWordFuncTypeBitPacked: boolean;
|
||||||
function KeyWordFuncSpecialize: boolean;
|
function KeyWordFuncSpecialize: boolean;
|
||||||
@ -153,7 +153,7 @@ type
|
|||||||
function KeyWordFuncTypeType: boolean;
|
function KeyWordFuncTypeType: boolean;
|
||||||
function KeyWordFuncTypeFile: boolean;
|
function KeyWordFuncTypeFile: boolean;
|
||||||
function KeyWordFuncTypePointer: boolean;
|
function KeyWordFuncTypePointer: boolean;
|
||||||
function KeyWordFuncTypeRecord: boolean;
|
function KeyWordFuncTypeRecordOld: boolean;
|
||||||
function KeyWordFuncTypeRecordCase: boolean;
|
function KeyWordFuncTypeRecordCase: boolean;
|
||||||
function KeyWordFuncTypeDefault: boolean;
|
function KeyWordFuncTypeDefault: boolean;
|
||||||
// procedures/functions/methods
|
// procedures/functions/methods
|
||||||
@ -399,34 +399,34 @@ begin
|
|||||||
if CompareSrcIdentifiers('BITPACKED',p) then exit(KeyWordFuncTypeBitPacked);
|
if CompareSrcIdentifiers('BITPACKED',p) then exit(KeyWordFuncTypeBitPacked);
|
||||||
'C':
|
'C':
|
||||||
case UpChars[p[1]] of
|
case UpChars[p[1]] of
|
||||||
'L': if CompareSrcIdentifiers('CLASS',p) then exit(KeyWordFuncClass);
|
'L': if CompareSrcIdentifiers('CLASS',p) then exit(KeyWordFuncTypeClass);
|
||||||
'P': if CompareSrcIdentifiers('CPPCLASS',p) then exit(KeyWordFuncClass);
|
'P': if CompareSrcIdentifiers('CPPCLASS',p) then exit(KeyWordFuncTypeClass);
|
||||||
end;
|
end;
|
||||||
'D':
|
'D':
|
||||||
if CompareSrcIdentifiers('DISPINTERFACE',p) then exit(KeyWordFuncClassInterface);
|
if CompareSrcIdentifiers('DISPINTERFACE',p) then exit(KeyWordFuncTypeClassInterface);
|
||||||
'F':
|
'F':
|
||||||
case UpChars[p[1]] of
|
case UpChars[p[1]] of
|
||||||
'I': if CompareSrcIdentifiers('FILE',p) then exit(KeyWordFuncTypeFile);
|
'I': if CompareSrcIdentifiers('FILE',p) then exit(KeyWordFuncTypeFile);
|
||||||
'U': if CompareSrcIdentifiers('FUNCTION',p) then exit(KeyWordFuncTypeProc);
|
'U': if CompareSrcIdentifiers('FUNCTION',p) then exit(KeyWordFuncTypeProc);
|
||||||
end;
|
end;
|
||||||
'I':
|
'I':
|
||||||
if CompareSrcIdentifiers('INTERFACE',p) then exit(KeyWordFuncClassInterface);
|
if CompareSrcIdentifiers('INTERFACE',p) then exit(KeyWordFuncTypeClassInterface);
|
||||||
'L':
|
'L':
|
||||||
if CompareSrcIdentifiers('LABEL',p) then exit(KeyWordFuncTypeLabel);
|
if CompareSrcIdentifiers('LABEL',p) then exit(KeyWordFuncTypeLabel);
|
||||||
'O':
|
'O':
|
||||||
if CompareSrcIdentifiers('OBJECT',p)
|
if CompareSrcIdentifiers('OBJECT',p)
|
||||||
or CompareSrcIdentifiers('OBJCCLASS',p)
|
or CompareSrcIdentifiers('OBJCCLASS',p)
|
||||||
or CompareSrcIdentifiers('OBJCCATEGORY',p) then
|
or CompareSrcIdentifiers('OBJCCATEGORY',p) then
|
||||||
exit(KeyWordFuncClass)
|
exit(KeyWordFuncTypeClass)
|
||||||
else if CompareSrcIdentifiers('OBJCPROTOCOL',p) then
|
else if CompareSrcIdentifiers('OBJCPROTOCOL',p) then
|
||||||
exit(KeyWordFuncClassInterface);
|
exit(KeyWordFuncTypeClassInterface);
|
||||||
'P':
|
'P':
|
||||||
case UpChars[p[1]] of
|
case UpChars[p[1]] of
|
||||||
'A': if CompareSrcIdentifiers('PACKED',p) then exit(KeyWordFuncTypePacked);
|
'A': if CompareSrcIdentifiers('PACKED',p) then exit(KeyWordFuncTypePacked);
|
||||||
'R': if CompareSrcIdentifiers('PROCEDURE',p) then exit(KeyWordFuncTypeProc);
|
'R': if CompareSrcIdentifiers('PROCEDURE',p) then exit(KeyWordFuncTypeProc);
|
||||||
end;
|
end;
|
||||||
'R':
|
'R':
|
||||||
if CompareSrcIdentifiers('RECORD',p) then exit(KeyWordFuncTypeRecord);
|
if CompareSrcIdentifiers('RECORD',p) then exit(KeyWordFuncTypeClass);
|
||||||
'S':
|
'S':
|
||||||
case UpChars[p[1]] of
|
case UpChars[p[1]] of
|
||||||
'E': if CompareSrcIdentifiers('SET',p) then exit(KeyWordFuncTypeSet);
|
'E': if CompareSrcIdentifiers('SET',p) then exit(KeyWordFuncTypeSet);
|
||||||
@ -441,7 +441,7 @@ end;
|
|||||||
|
|
||||||
function TPascalParserTool.ParseInnerClass(StartPos, WordLen: integer
|
function TPascalParserTool.ParseInnerClass(StartPos, WordLen: integer
|
||||||
): boolean;
|
): boolean;
|
||||||
// KeyWordFunctions for parsing in a class/object
|
// KeyWordFunctions for parsing in a class/object/record
|
||||||
var
|
var
|
||||||
p: PChar;
|
p: PChar;
|
||||||
begin
|
begin
|
||||||
@ -450,6 +450,7 @@ begin
|
|||||||
case UpChars[p^] of
|
case UpChars[p^] of
|
||||||
'C':
|
'C':
|
||||||
case UpChars[p[1]] of
|
case UpChars[p[1]] of
|
||||||
|
'A': if CompareSrcIdentifiers(p,'CASE') then exit(KeyWordFuncTypeRecordCase);
|
||||||
'L': if CompareSrcIdentifiers(p,'CLASS') then exit(KeyWordFuncClassClass);
|
'L': if CompareSrcIdentifiers(p,'CLASS') then exit(KeyWordFuncClassClass);
|
||||||
'O': if CompareSrcIdentifiers(p,'CONSTRUCTOR') then exit(KeyWordFuncClassMethod)
|
'O': if CompareSrcIdentifiers(p,'CONSTRUCTOR') then exit(KeyWordFuncClassMethod)
|
||||||
else if CompareSrcIdentifiers(p,'CONST') then exit(KeyWordFuncClassConstSection);
|
else if CompareSrcIdentifiers(p,'CONST') then exit(KeyWordFuncClassConstSection);
|
||||||
@ -3614,11 +3615,8 @@ begin
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPascalParserTool.KeyWordFuncClass: boolean;
|
function TPascalParserTool.KeyWordFuncTypeClass: boolean;
|
||||||
// class, object
|
// class, object, record
|
||||||
// this is a quick parser, which will only create one node for each class
|
|
||||||
// the nodes for the methods and properties are created in a second
|
|
||||||
// parsing phase (in KeyWordFuncClassMethod)
|
|
||||||
var
|
var
|
||||||
ClassAtomPos: TAtomPosition;
|
ClassAtomPos: TAtomPosition;
|
||||||
ContextDesc: Word;
|
ContextDesc: Word;
|
||||||
@ -3626,23 +3624,13 @@ var
|
|||||||
ClassDesc: TCodeTreeNodeDesc;
|
ClassDesc: TCodeTreeNodeDesc;
|
||||||
ClassNode: TCodeTreeNode;
|
ClassNode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
ContextDesc:=CurNode.Desc;
|
|
||||||
if not (ContextDesc in [ctnTypeDefinition,ctnGenericType,
|
|
||||||
ctnVarDefinition,ctnConstDefinition])
|
|
||||||
then
|
|
||||||
SaveRaiseExceptionFmt(ctsAnonymDefinitionsAreNotAllowed,['class']);
|
|
||||||
if CurNode.Parent.Desc<>ctnTypeSection then
|
|
||||||
SaveRaiseExceptionFmt(ctsNestedDefinitionsAreNotAllowed,['class']);
|
|
||||||
if LastUpAtomIs(0,'PACKED') or LastUpAtomIs(0,'BITPACKED') then begin
|
|
||||||
ClassAtomPos:=LastAtoms.GetValueAt(0);
|
|
||||||
end else begin
|
|
||||||
ClassAtomPos:=CurPos;
|
|
||||||
end;
|
|
||||||
// class or 'class of' start found
|
// class or 'class of' start found
|
||||||
if UpAtomIs('CLASS') then
|
if UpAtomIs('CLASS') then
|
||||||
ClassDesc:=ctnClass
|
ClassDesc:=ctnClass
|
||||||
else if UpAtomIs('OBJECT') then
|
else if UpAtomIs('OBJECT') then
|
||||||
ClassDesc:=ctnObject
|
ClassDesc:=ctnObject
|
||||||
|
else if UpAtomIs('RECORD') then
|
||||||
|
ClassDesc:=ctnRecordType
|
||||||
else if UpAtomIs('OBJCCLASS') then
|
else if UpAtomIs('OBJCCLASS') then
|
||||||
ClassDesc:=ctnObjCClass
|
ClassDesc:=ctnObjCClass
|
||||||
else if UpAtomIs('OBJCCATEGORY') then
|
else if UpAtomIs('OBJCCATEGORY') then
|
||||||
@ -3651,13 +3639,26 @@ begin
|
|||||||
ClassDesc:=ctnCPPClass
|
ClassDesc:=ctnCPPClass
|
||||||
else
|
else
|
||||||
RaiseStringExpectedButAtomFound('class');
|
RaiseStringExpectedButAtomFound('class');
|
||||||
|
ContextDesc:=CurNode.Desc;
|
||||||
|
if ClassDesc<>ctnRecordType then begin
|
||||||
|
if not (ContextDesc in [ctnTypeDefinition,ctnGenericType])
|
||||||
|
then
|
||||||
|
SaveRaiseExceptionFmt(ctsAnonymDefinitionsAreNotAllowed,[GetAtom]);
|
||||||
|
if CurNode.Parent.Desc<>ctnTypeSection then
|
||||||
|
SaveRaiseExceptionFmt(ctsNestedDefinitionsAreNotAllowed,[GetAtom]);
|
||||||
|
end;
|
||||||
|
if LastUpAtomIs(0,'PACKED') or LastUpAtomIs(0,'BITPACKED') then begin
|
||||||
|
ClassAtomPos:=LastAtoms.GetValueAt(0);
|
||||||
|
end else begin
|
||||||
|
ClassAtomPos:=CurPos;
|
||||||
|
end;
|
||||||
CreateChildNode;
|
CreateChildNode;
|
||||||
ClassNode:=CurNode;
|
ClassNode:=CurNode;
|
||||||
CurNode.Desc:=ClassDesc;
|
CurNode.Desc:=ClassDesc;
|
||||||
CurNode.StartPos:=ClassAtomPos.StartPos;
|
CurNode.StartPos:=ClassAtomPos.StartPos;
|
||||||
IsForward:=true;
|
IsForward:=true;
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
if UpAtomIs('OF') then begin
|
if (ClassDesc=ctnClass) and UpAtomIs('OF') then begin
|
||||||
IsForward:=false;
|
IsForward:=false;
|
||||||
CurNode.Desc:=ctnClassOfType;
|
CurNode.Desc:=ctnClassOfType;
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
@ -3691,7 +3692,7 @@ begin
|
|||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else if UpAtomIs('EXTERNAL') and (ClassDesc in [ctnObjCClass]) then
|
else if UpAtomIs('EXTERNAL') and (ClassDesc=ctnObjCClass) then
|
||||||
begin
|
begin
|
||||||
CreateChildNode;
|
CreateChildNode;
|
||||||
CurNode.Desc:=ctnClassExternal;
|
CurNode.Desc:=ctnClassExternal;
|
||||||
@ -3775,7 +3776,7 @@ begin
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPascalParserTool.KeyWordFuncClassInterface: boolean;
|
function TPascalParserTool.KeyWordFuncTypeClassInterface: boolean;
|
||||||
// class interface, dispinterface
|
// class interface, dispinterface
|
||||||
var
|
var
|
||||||
IntfAtomPos: TAtomPosition;
|
IntfAtomPos: TAtomPosition;
|
||||||
@ -4187,7 +4188,7 @@ begin
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPascalParserTool.KeyWordFuncTypeRecord: boolean;
|
function TPascalParserTool.KeyWordFuncTypeRecordOld: boolean;
|
||||||
{ read variable type 'record'
|
{ read variable type 'record'
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
@ -4256,10 +4257,45 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TPascalParserTool.KeyWordFuncTypeRecordCase: boolean;
|
function TPascalParserTool.KeyWordFuncTypeRecordCase: boolean;
|
||||||
|
{ after parsing CurPos is on the atom behind the case
|
||||||
|
|
||||||
|
record
|
||||||
|
i: packed record
|
||||||
|
j: integer;
|
||||||
|
k: record end;
|
||||||
|
case y: integer of
|
||||||
|
0: (a: integer);
|
||||||
|
1,2,3: (b: array[char] of char; c: char);
|
||||||
|
3: ( d: record
|
||||||
|
case byte of
|
||||||
|
10: (i: integer; );
|
||||||
|
11: (y: byte);
|
||||||
|
end; );
|
||||||
|
4: (e: integer;
|
||||||
|
case z of
|
||||||
|
8: (f: integer)
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
|
||||||
|
procedure RaiseCaseOnlyAllowedInRecords;
|
||||||
|
begin
|
||||||
|
SaveRaiseException('Case only allowed in records');
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if not UpAtomIs('CASE') then
|
if not UpAtomIs('CASE') then
|
||||||
SaveRaiseException('[TPascalParserTool.KeyWordFuncTypeRecordCase] '
|
SaveRaiseException('[TPascalParserTool.KeyWordFuncTypeRecordCase] '
|
||||||
+'internal error');
|
+'internal error');
|
||||||
|
if (CurNode.Parent.Desc=ctnRecordVariant)
|
||||||
|
or ((CurNode.Parent.Desc in AllClassSections)
|
||||||
|
and (CurNode.Parent.Parent.Desc=ctnRecordType))
|
||||||
|
then begin
|
||||||
|
// ok
|
||||||
|
end else begin
|
||||||
|
RaiseCaseOnlyAllowedInRecords;
|
||||||
|
end;
|
||||||
CreateChildNode;
|
CreateChildNode;
|
||||||
CurNode.Desc:=ctnRecordCase;
|
CurNode.Desc:=ctnRecordCase;
|
||||||
ReadNextAtom; // read ordinal type
|
ReadNextAtom; // read ordinal type
|
||||||
@ -4335,7 +4371,7 @@ begin
|
|||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
until false;
|
until false;
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
if (CurPos.Flag in [cafEnd,cafRoundBracketClose]) then begin
|
if (CurPos.Flag in [cafEnd,cafRoundBracketClose,cafEdgedBracketClose]) then begin
|
||||||
CurNode.EndPos:=CurPos.StartPos;
|
CurNode.EndPos:=CurPos.StartPos;
|
||||||
EndChildNode; // close variant
|
EndChildNode; // close variant
|
||||||
break;
|
break;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user