codetools: parsing advanced records

git-svn-id: trunk@29359 -
This commit is contained in:
mattias 2011-02-03 20:38:14 +00:00
parent 0324c50205
commit 05be735961
10 changed files with 135 additions and 79 deletions

View File

@ -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;

View File

@ -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

View File

@ -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:='';

View File

@ -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.

View File

@ -108,7 +108,7 @@ type
} }
const const
AllNodeCacheDescs = AllNodeCacheDescs =
AllClasses+[ctnProcedure, ctnRecordType, ctnWithStatement]; AllClasses+[ctnProcedure, ctnWithStatement];
type type
TNodeCacheEntryFlag = (ncefSearchedInParents, ncefSearchedInAncestors); TNodeCacheEntryFlag = (ncefSearchedInParents, ncefSearchedInAncestors);

View File

@ -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])

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;