codetools: support new class/generics syntax. like the next:

{ 
 TFoo = class
  const
    Value = 5;
  type
    TBar = integer;
  var
    FSomeField: Integer;
    procedure Dosomething;
  end;  
}

git-svn-id: trunk@28513 -
This commit is contained in:
paul 2010-11-27 18:25:25 +00:00
parent e2c48f0cd4
commit 188361e605
6 changed files with 100 additions and 120 deletions

View File

@ -5901,7 +5901,7 @@ begin
if ClassSectionNode.NextBrother<>nil then
Indent:=GetLineIndent(Src,ClassSectionNode.StartPos)
+ASourceChangeCache.BeautifyCodeOptions.Indent;
end else if (ClassSectionNode.Desc in (AllClassBaseSections+AllClassTypeSections))
end else if (ClassSectionNode.Desc in (AllClassBaseSections+[ctnClassType]))
then begin
// skip keyword
MoveCursorToCleanPos(InsertPos);

View File

@ -95,20 +95,16 @@ const
ctnClassSealed = 41;
ctnClassInheritance = 42;
ctnClassGUID = 43;
ctnClassTypePrivate = 44;
ctnClassTypeProtected = 45;
ctnClassTypePublic = 46;
ctnClassTypePublished = 47;
ctnClassVarPrivate = 48;
ctnClassVarProtected = 49;
ctnClassVarPublic = 50;
ctnClassVarPublished = 51;
ctnClassPrivate = 52;
ctnClassProtected = 53;
ctnClassPublic = 54;
ctnClassPublished = 55;
ctnProperty = 56;
ctnMethodMap = 57;
ctnClassConst = 44;
ctnClassType = 45;
ctnClassVar = 46;
ctnClassClassVar = 47;
ctnClassPrivate = 48;
ctnClassProtected = 49;
ctnClassPublic = 50;
ctnClassPublished = 51;
ctnProperty = 52;
ctnMethodMap = 53;
ctnProcedure = 60; // childs: ctnProcedureHead, sections, ctnBeginBlock/ctnAsmBlock
ctnProcedureHead = 61; // childs: ctnParameterList, operator: ctnVarDefinition, operator/function: ctnResultType
@ -159,14 +155,8 @@ const
+ [ctnInterface, ctnImplementation, ctnInitialization, ctnFinalization];
AllClassBaseSections =
[ctnClassPublic,ctnClassPublished,ctnClassPrivate,ctnClassProtected];
AllClassTypeSections =
[ctnClassTypePublic,ctnClassTypePublished,ctnClassTypePrivate,
ctnClassTypeProtected];
AllClassVarSections =
[ctnClassVarPublic,ctnClassVarPublished,ctnClassVarPrivate,
ctnClassVarProtected];
AllClassSections =
AllClassBaseSections+AllClassTypeSections+AllClassVarSections;
AllClassBaseSections+[ctnClassConst, ctnClassType, ctnClassVar, ctnClassClassVar];
AllClasses =
[ctnClass,ctnClassInterface,ctnDispinterface,ctnObject,
ctnObjCClass,ctnObjCCategory,ctnObjCProtocol,
@ -386,14 +376,10 @@ begin
ctnClassPrivate: Result:='Private';
ctnClassProtected: Result:='Protected';
ctnClassPublic: Result:='Public';
ctnClassTypePublished: Result:='Type Published';
ctnClassTypePrivate: Result:='Type Private';
ctnClassTypeProtected: Result:='Type Protected';
ctnClassTypePublic: Result:='Type Public';
ctnClassVarPublished: Result:='Var Published';
ctnClassVarPrivate: Result:='Var Private';
ctnClassVarProtected: Result:='Var Protected';
ctnClassVarPublic: Result:='Var Public';
ctnClassConst: Result:='Const';
ctnClassType: Result:='Type';
ctnClassVar: Result:='Var';
ctnClassClassVar: Result:='Class Var';
ctnClassAbstract: Result:='abstract';
ctnClassSealed: Result:='sealed';

View File

@ -2148,14 +2148,19 @@ begin
while ANode<>nil do begin
if ANode.Desc in AllClassSections then begin
case ANode.Desc of
ctnClassPrivate,ctnClassTypePrivate,ctnClassVarPrivate:
ctnClassPrivate:
Result:=Result+'private ';
ctnClassProtected,ctnClassTypeProtected,ctnClassVarProtected:
ctnClassProtected:
Result:=Result+'protected ';
ctnClassPublic,ctnClassTypePublic,ctnClassVarPublic:
ctnClassPublic:
Result:=Result+'public ';
ctnClassPublished,ctnClassTypePublished,ctnClassVarPublished:
ctnClassPublished:
Result:=Result+'published ';
else
begin
ANode:=ANode.Parent;
Continue;
end;
end;
break;
end else if ANode.Desc in ([ctnParameterList]+AllClasses) then
@ -2967,8 +2972,7 @@ var
ctnLabelSection, ctnPropertySection,
ctnInterface, ctnImplementation,
ctnClassPublished,ctnClassPublic,ctnClassProtected,ctnClassPrivate,
ctnClassTypePublished,ctnClassTypePublic,ctnClassTypeProtected,ctnClassTypePrivate,
ctnClassVarPublished,ctnClassVarPublic,ctnClassVarProtected,ctnClassVarPrivate,
ctnClassConst,ctnClassType,ctnClassVar,ctnClassClassVar,
ctnRecordVariant,
ctnProcedureHead, ctnParameterList,
ctnClassInheritance:
@ -3087,8 +3091,7 @@ begin
ctnLabelSection, ctnPropertySection,
ctnInterface, ctnImplementation,
ctnClassPublic, ctnClassPrivate, ctnClassProtected, ctnClassPublished,
ctnClassTypePublished,ctnClassTypePublic,ctnClassTypeProtected,ctnClassTypePrivate,
ctnClassVarPublished,ctnClassVarPublic,ctnClassVarProtected,ctnClassVarPrivate,
ctnClassConst, ctnClassType, ctnClassVar, ctnClassClassVar,
ctnClass, ctnClassInterface, ctnDispinterface, ctnObject,
ctnObjCClass, ctnObjCCategory, ctnObjCProtocol, ctnCPPClass,
ctnRecordType, ctnRecordVariant,

View File

@ -1944,7 +1944,7 @@ var
Node:=CursorNode;
Can:=false;
if (Node.Parent<>nil)
and (Node.Parent.Desc in (AllClassBaseSections+AllClassVarSections))
and (Node.Parent.Desc in [ctnClassVar,ctnClassClassVar])
and (Node.Desc=ctnVarDefinition)
and (CurrentIdentifierList.StartAtomBehind.Flag<>cafColon) then begin
{ cursor is at a class variable definition without type

View File

@ -138,6 +138,7 @@ type
function KeyWordFuncExports: boolean;
function KeyWordFuncLabel: boolean;
function KeyWordFuncProperty: boolean;
procedure ReadConst;
// types
procedure ReadEqualsType;
function KeyWordFuncClass: boolean;
@ -160,6 +161,7 @@ type
function KeyWordFuncBeginEnd: boolean;
// class/object elements
function KeyWordFuncClassSection: boolean;
function KeyWordFuncClassConstSection: boolean;
function KeyWordFuncClassTypeSection: boolean;
function KeyWordFuncClassVarSection: boolean;
function KeyWordFuncClassClass: boolean;
@ -443,7 +445,8 @@ begin
'C':
case UpChars[p[1]] of
'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);
end;
'D':
if CompareSrcIdentifiers(p,'DESTRUCTOR') then exit(KeyWordFuncClassMethod);
@ -875,7 +878,7 @@ begin
end;
function TPascalParserTool.KeyWordFuncClassIdentifier: boolean;
{ parse class variable or type
{ parse class variable or type or const
examples for variables:
Name: TypeName;
@ -902,13 +905,21 @@ function TPascalParserTool.KeyWordFuncClassIdentifier: boolean;
MyRange: 3..5;
}
begin
if CurNode.Desc in AllClassTypeSections then begin
if CurNode.Desc = ctnClassType then begin
// create type definition node
CreateChildNode;
CurNode.Desc:=ctnTypeDefinition;
ReadEqualsType;
CurNode.EndPos:=CurPos.EndPos;
EndChildNode;
end else
if CurNode.Desc = ctnClassConst then begin
// create const definition node
CreateChildNode;
CurNode.Desc:=ctnConstDefinition;
ReadConst;
CurNode.EndPos:=CurPos.EndPos;
EndChildNode;
end else begin
// create variable definition node
CreateChildNode;
@ -1097,6 +1108,17 @@ begin
Result:=true;
end;
function TPascalParserTool.KeyWordFuncClassConstSection: boolean;
begin
// end last section
CurNode.EndPos:=CurPos.StartPos;
EndChildNode;
// start new section
CreateChildNode;
CurNode.Desc:=ctnClassConst;
Result:=true;
end;
function TPascalParserTool.KeyWordFuncClassTypeSection: boolean;
begin
// end last section
@ -1104,39 +1126,14 @@ begin
EndChildNode;
// start new section
CreateChildNode;
if UpAtomIs('CLASS') then ReadNextAtom;
ReadNextAtom;
if UpAtomIs('PUBLIC') then
CurNode.Desc:=ctnClassTypePublic
else if UpAtomIs('PRIVATE') then
CurNode.Desc:=ctnClassTypePrivate
else if UpAtomIs('PROTECTED') then
CurNode.Desc:=ctnClassTypeProtected
else if UpAtomIs('PUBLISHED') then
CurNode.Desc:=ctnClassTypePublished
else begin
if CurNode.PriorBrother<>nil then begin
case CurNode.PriorBrother.Desc of
ctnClassPrivate: CurNode.Desc:=ctnClassTypePrivate;
ctnClassProtected: CurNode.Desc:=ctnClassTypeProtected;
ctnClassPublic: CurNode.Desc:=ctnClassTypePublic;
ctnClassPublished: CurNode.Desc:=ctnClassTypePublished;
else
RaiseStringExpectedButAtomFound('public');
end;
end;
UndoReadNextAtom;
end;
CurNode.Desc:=ctnClassType;
Result:=true;
end;
function TPascalParserTool.KeyWordFuncClassVarSection: boolean;
{
var private
var protected
var public
var published
class var private
var
class var
}
begin
// end last section
@ -1144,19 +1141,13 @@ begin
EndChildNode;
// start new section
CreateChildNode;
CurNode.Desc:=ctnClassVarPublic;
if UpAtomIs('CLASS') then ReadNextAtom;
ReadNextAtom;
if UpAtomIs('PUBLIC') then
CurNode.Desc:=ctnClassVarPublic
else if UpAtomIs('PRIVATE') then
CurNode.Desc:=ctnClassVarPrivate
else if UpAtomIs('PROTECTED') then
CurNode.Desc:=ctnClassVarProtected
else if UpAtomIs('PUBLISHED') then
CurNode.Desc:=ctnClassVarPublished
if UpAtomIs('CLASS') then
begin
CurNode.Desc:=ctnClassClassVar;
ReadNextAtom;
end
else
RaiseStringExpectedButAtomFound('public');
CurNode.Desc:=ctnClassVar;
Result:=true;
end;
@ -1167,7 +1158,6 @@ function TPascalParserTool.KeyWordFuncClassClass: boolean;
class constructor
class destructor
class var
class type
}
begin
ReadNextAtom;
@ -3454,32 +3444,7 @@ begin
then begin
CreateChildNode;
CurNode.Desc:=ctnConstDefinition;
ReadNextAtom;
if (CurPos.Flag=cafColon) then begin
// read type
ReadNextAtom;
ParseType(CurPos.StartPos,CurPos.EndPos-CurPos.StartPos);
end;
if (CurPos.Flag<>cafEqual) then
RaiseCharExpectedButAtomFound('=');
// read constant
ReadNextAtom;
CreateChildNode;
CurNode.Desc:=ctnConstant;
repeat
if (CurPos.Flag in [cafRoundBracketOpen,cafEdgedBracketOpen]) then
ReadTilBracketClose(true);
if (CurPos.Flag in AllCommonAtomWords)
and (not IsKeyWordInConstAllowed.DoItCaseInsensitive(Src,
CurPos.StartPos,CurPos.EndPos-CurPos.StartPos))
and AtomIsKeyWord then
RaiseStringExpectedButAtomFound('constant');
if (CurPos.Flag=cafSemicolon) then break;
CurNode.EndPos:=CurPos.EndPos;
ReadNextAtom;
until (CurPos.StartPos>SrcLen);
// close ctnConstant node
EndChildNode;
ReadConst;
// close ctnConstDefinition node
CurNode.EndPos:=CurPos.EndPos;
EndChildNode;
@ -3661,6 +3626,36 @@ begin
Result:=true;
end;
procedure TPascalParserTool.ReadConst;
begin
ReadNextAtom;
if (CurPos.Flag=cafColon) then begin
// read type
ReadNextAtom;
ParseType(CurPos.StartPos,CurPos.EndPos-CurPos.StartPos);
end;
if (CurPos.Flag<>cafEqual) then
RaiseCharExpectedButAtomFound('=');
// read constant
ReadNextAtom;
CreateChildNode;
CurNode.Desc:=ctnConstant;
repeat
if (CurPos.Flag in [cafRoundBracketOpen,cafEdgedBracketOpen]) then
ReadTilBracketClose(true);
if (CurPos.Flag in AllCommonAtomWords)
and (not IsKeyWordInConstAllowed.DoItCaseInsensitive(Src,
CurPos.StartPos,CurPos.EndPos-CurPos.StartPos))
and AtomIsKeyWord then
RaiseStringExpectedButAtomFound('constant');
if (CurPos.Flag=cafSemicolon) then break;
CurNode.EndPos:=CurPos.EndPos;
ReadNextAtom;
until (CurPos.StartPos>SrcLen);
// close ctnConstant node
EndChildNode;
end;
procedure TPascalParserTool.ReadEqualsType;
// read = type;
begin
@ -3826,7 +3821,7 @@ begin
SaveRaiseException(ctsEndForClassNotFound);
'C':
if CompareSrcIdentifiers(p,'CONST')
and (BracketLvl=0) then
and (BracketLvl>0) then
SaveRaiseException(ctsEndForClassNotFound);
'I':
if CompareSrcIdentifiers(p,'INTERFACE')

View File

@ -1105,7 +1105,7 @@ begin
end;
end;
ctnClassTypePrivate..ctnClassPublished:
ctnClassConst..ctnClassPublished:
begin
if (cefcUnsortedClassVisibility in ObserverCats)
and (CodeNode.PriorBrother<>nil)
@ -2222,18 +2222,14 @@ const
Result:=4;
// class sections
ctnClassTypePrivate,
ctnClassTypeProtected,
ctnClassTypePublic,
ctnClassTypePublished,
ctnClassVarPrivate,
ctnClassVarProtected,
ctnClassVarPublic,
ctnClassVarPublished,
ctnClassConst,
ctnClassType,
ctnClassVar,
ctnClassClassVar,
ctnClassPrivate,
ctnClassProtected,
ctnClassPublic,
ctnClassPublished : Result:=Desc-ctnClassTypePrivate;
ctnClassPublished : Result:=Desc-ctnClassConst;
else Result:=10000;
end;