Browse Source

* Various small fixes

git-svn-id: trunk@45515 -
michael 5 years ago
parent
commit
8b07fe33e6

+ 1 - 1
packages/fcl-passrc/src/pastree.pp

@@ -768,7 +768,7 @@ type
     okDispInterface, okObjcClass, okObjcCategory,
     okDispInterface, okObjcClass, okObjcCategory,
     okObjcProtocol);
     okObjcProtocol);
 const
 const
-  okWithFields = [okObject, okClass];
+  okWithFields = [okObject, okClass, okObjcClass, okObjcCategory];
   okAllHelpers = [okClassHelper,okRecordHelper,okTypeHelper];
   okAllHelpers = [okClassHelper,okRecordHelper,okTypeHelper];
   okWithClassFields = okWithFields+okAllHelpers;
   okWithClassFields = okWithFields+okAllHelpers;
   okObjCClasses = [okObjcClass, okObjcCategory, okObjcProtocol];
   okObjCClasses = [okObjcClass, okObjcCategory, okObjcProtocol];

+ 46 - 14
packages/fcl-passrc/src/pparser.pp

@@ -371,8 +371,8 @@ type
     function ParseExprOperand(AParent : TPasElement): TPasExpr;
     function ParseExprOperand(AParent : TPasElement): TPasExpr;
     function ParseExpIdent(AParent : TPasElement): TPasExpr; deprecated 'use ParseExprOperand instead'; // since fpc 3.3.1
     function ParseExpIdent(AParent : TPasElement): TPasExpr; deprecated 'use ParseExprOperand instead'; // since fpc 3.3.1
     procedure DoParseClassType(AType: TPasClassType);
     procedure DoParseClassType(AType: TPasClassType);
-    procedure DoParseClassExternalHeader(AObjKind: TPasObjKind;
-      out AExternalNameSpace, AExternalName: string);
+    Function DoParseClassExternalHeader(AObjKind: TPasObjKind;
+      out AExternalNameSpace, AExternalName: string) : Boolean;
     procedure DoParseArrayType(ArrType: TPasArrayType);
     procedure DoParseArrayType(ArrType: TPasArrayType);
     function DoParseExpression(AParent: TPaselement;InitExpr: TPasExpr=nil; AllowEqual : Boolean = True): TPasExpr;
     function DoParseExpression(AParent: TPaselement;InitExpr: TPasExpr=nil; AllowEqual : Boolean = True): TPasExpr;
     function DoParseConstValueExpression(AParent: TPasElement): TPasExpr;
     function DoParseConstValueExpression(AParent: TPasElement): TPasExpr;
@@ -5581,6 +5581,16 @@ function TPasParser.ParseProperty(Parent: TPasElement; const AName: String;
     until CurToken<>tkComma;
     until CurToken<>tkComma;
   end;
   end;
 
 
+  procedure ConsumeSemi;
+  begin
+    if (CurToken = tkSemicolon) then
+      begin
+      NextToken;
+      if IsCurTokenHint then
+        UngetToken;
+      end;
+  end;
+
 var
 var
   isArray , ok, IsClass: Boolean;
   isArray , ok, IsClass: Boolean;
   ObjKind: TPasObjKind;
   ObjKind: TPasObjKind;
@@ -5666,7 +5676,7 @@ begin
       end;
       end;
     if CurTokenIsIdentifier('DEFAULT') then
     if CurTokenIsIdentifier('DEFAULT') then
       begin
       begin
-      if not (ObjKind in [okClass]) then
+      if not (ObjKind in [okClass,okClassHelper]) then // FPC allows it in type helpers
         ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['DEFAULT',ObjKindNames[ObjKind]]);
         ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['DEFAULT',ObjKindNames[ObjKind]]);
       if isArray then
       if isArray then
         ParseExc(nParserArrayPropertiesCannotHaveDefaultValue,SParserArrayPropertiesCannotHaveDefaultValue);
         ParseExc(nParserArrayPropertiesCannotHaveDefaultValue,SParserArrayPropertiesCannotHaveDefaultValue);
@@ -5700,8 +5710,11 @@ begin
         end;
         end;
       // Handle hints
       // Handle hints
       while DoCheckHint(Result) do
       while DoCheckHint(Result) do
-        NextToken;
-      if Result.Hints=[] then
+        begin
+        NextToken; // eat Hint token
+        ConsumeSemi; // Now on hint token or semicolon
+        end;
+//      if Result.Hints=[] then
         UngetToken;
         UngetToken;
       end
       end
     else if CurToken=tkend then
     else if CurToken=tkend then
@@ -5724,6 +5737,10 @@ var
 begin
 begin
   BeginBlock := TPasImplBeginBlock(CreateElement(TPasImplBeginBlock, '', Parent));
   BeginBlock := TPasImplBeginBlock(CreateElement(TPasImplBeginBlock, '', Parent));
   Parent.Body := BeginBlock;
   Parent.Body := BeginBlock;
+  // these can be used in code for typecasts
+  Scanner.SetNonToken(tkobjccategory);
+  Scanner.SetNonToken(tkobjcprotocol);
+  Scanner.SetNonToken(tkobjcclass);
   repeat
   repeat
     NextToken;
     NextToken;
 //    writeln('TPasParser.ParseProcBeginBlock ',curtokenstring);
 //    writeln('TPasParser.ParseProcBeginBlock ',curtokenstring);
@@ -5737,6 +5754,10 @@ begin
         ExpectToken(tkend);
         ExpectToken(tkend);
     end;
     end;
   until false;
   until false;
+  // A declaration can follow...
+  Scanner.UnSetNonToken(tkobjccategory);
+  Scanner.UnSetNonToken(tkobjcprotocol);
+  Scanner.UnSetNonToken(tkobjcclass);
   Proc:=Parent.Parent as TPasProcedure;
   Proc:=Parent.Parent as TPasProcedure;
   if Proc.GetProcTypeEnum in [ptAnonymousProcedure,ptAnonymousFunction] then
   if Proc.GetProcTypeEnum in [ptAnonymousProcedure,ptAnonymousFunction] then
     NextToken
     NextToken
@@ -7326,7 +7347,7 @@ begin
       begin
       begin
       case AType.ObjKind of
       case AType.ObjKind of
       okClass,okObject,
       okClass,okObject,
-      okClassHelper,okRecordHelper,okTypeHelper: ;
+      okClassHelper,okRecordHelper,okTypeHelper, okObjCClass, okObjcCategory, okObjcProtocol : ;
       else
       else
         ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['CLASS',ObjKindNames[AType.ObjKind]]);
         ParseExc(nParserXNotAllowedInY,SParserXNotAllowedInY,['CLASS',ObjKindNames[AType.ObjKind]]);
       end;
       end;
@@ -7384,7 +7405,7 @@ begin
       CheckToken(tkend);
       CheckToken(tkend);
     NextToken;
     NextToken;
     AType.AncestorType := ParseTypeReference(AType,false,Expr);
     AType.AncestorType := ParseTypeReference(AType,false,Expr);
-    if AType.ObjKind=okClass then
+    if AType.ObjKind in [okClass,okObjCClass] then
       while CurToken=tkComma do
       while CurToken=tkComma do
         begin
         begin
         NextToken;
         NextToken;
@@ -7417,17 +7438,27 @@ begin
     end;
     end;
 end;
 end;
 
 
-procedure TPasParser.DoParseClassExternalHeader(AObjKind: TPasObjKind; out
-  AExternalNameSpace, AExternalName: string);
+function TPasParser.DoParseClassExternalHeader(AObjKind: TPasObjKind; out AExternalNameSpace, AExternalName: string): Boolean;
 begin
 begin
-  if ((AObjKind in [okClass,okInterface]) and (msExternalClass in CurrentModeswitches)
-      and CurTokenIsIdentifier('external')) then
+  Result:=False;
+  if ((aObjKind in [okObjcCategory,okObjcClass]) or
+      ((AObjKind in [okClass,okInterface]) and (msExternalClass in CurrentModeswitches)))
+      and CurTokenIsIdentifier('external') then
     begin
     begin
+    Result:=True;
     NextToken;
     NextToken;
     if CurToken<>tkString then
     if CurToken<>tkString then
       UnGetToken
       UnGetToken
     else
     else
       AExternalNameSpace:=CurTokenString;
       AExternalNameSpace:=CurTokenString;
+    if (aObjKind in [okObjcCategory,okObjcClass]) then
+      begin
+      // Name is optional in objcclass/category
+      NextToken;
+      if CurToken=tkBraceOpen then
+        exit;
+      UnGetToken;
+      end;
     ExpectIdentifier;
     ExpectIdentifier;
     If Not CurTokenIsIdentifier('Name')  then
     If Not CurTokenIsIdentifier('Name')  then
       ParseExc(nParserExpectedExternalClassName,SParserExpectedExternalClassName);
       ParseExc(nParserExpectedExternalClassName,SParserExpectedExternalClassName);
@@ -7508,9 +7539,10 @@ function TPasParser.ParseClassDecl(Parent: TPasElement;
   AObjKind: TPasObjKind; PackMode: TPackMode): TPasType;
   AObjKind: TPasObjKind; PackMode: TPackMode): TPasType;
 
 
 Var
 Var
-  ok: Boolean;
+  isExternal,ok: Boolean;
   AExternalNameSpace,AExternalName : String;
   AExternalNameSpace,AExternalName : String;
   PCT:TPasClassType;
   PCT:TPasClassType;
+
 begin
 begin
   NextToken;
   NextToken;
   if (AObjKind = okClass) and (CurToken = tkOf) then
   if (AObjKind = okClass) and (CurToken = tkOf) then
@@ -7530,7 +7562,7 @@ begin
     end;
     end;
     exit;
     exit;
     end;
     end;
-  DoParseClassExternalHeader(AObjKind,AExternalNameSpace,AExternalName);
+  isExternal:=DoParseClassExternalHeader(AObjKind,AExternalNameSpace,AExternalName);
   if AObjKind in okAllHelpers then
   if AObjKind in okAllHelpers then
     begin
     begin
     if not CurTokenIsIdentifier('Helper') then
     if not CurTokenIsIdentifier('Helper') then
@@ -7543,7 +7575,7 @@ begin
   ok:=false;
   ok:=false;
   try
   try
     PCT.HelperForType:=nil;
     PCT.HelperForType:=nil;
-    PCT.IsExternal:=(AExternalName<>'');
+    PCT.IsExternal:=IsExternal;
     if AExternalName<>'' then
     if AExternalName<>'' then
       PCT.ExternalName:={$ifdef pas2js}DeQuoteString{$else}AnsiDequotedStr{$endif}(AExternalName,'''');
       PCT.ExternalName:={$ifdef pas2js}DeQuoteString{$else}AnsiDequotedStr{$endif}(AExternalName,'''');
     if AExternalNameSpace<>'' then
     if AExternalNameSpace<>'' then

+ 6 - 0
packages/fcl-passrc/src/pscanner.pp

@@ -3672,6 +3672,7 @@ begin
     SetMode(msFpc,FPCModeSwitches,false,bsFPCMode);
     SetMode(msFpc,FPCModeSwitches,false,bsFPCMode);
     SetNonToken(tkobjcclass);
     SetNonToken(tkobjcclass);
     SetNonToken(tkobjcprotocol);
     SetNonToken(tkobjcprotocol);
+    SetNonToken(tkobjcCategory);
     end;
     end;
   'OBJFPC':
   'OBJFPC':
     begin
     begin
@@ -3680,6 +3681,7 @@ begin
     UnsetNonToken(tkspecialize);
     UnsetNonToken(tkspecialize);
     SetNonToken(tkobjcclass);
     SetNonToken(tkobjcclass);
     SetNonToken(tkobjcprotocol);
     SetNonToken(tkobjcprotocol);
+    SetNonToken(tkobjcCategory);
     end;
     end;
   'DELPHI':
   'DELPHI':
     begin
     begin
@@ -3688,6 +3690,7 @@ begin
     SetNonToken(tkspecialize);
     SetNonToken(tkspecialize);
     SetNonToken(tkobjcclass);
     SetNonToken(tkobjcclass);
     SetNonToken(tkobjcprotocol);
     SetNonToken(tkobjcprotocol);
+    SetNonToken(tkobjcCategory);
     end;
     end;
   'DELPHIUNICODE':
   'DELPHIUNICODE':
     begin
     begin
@@ -3696,6 +3699,7 @@ begin
     SetNonToken(tkspecialize);
     SetNonToken(tkspecialize);
     SetNonToken(tkobjcclass);
     SetNonToken(tkobjcclass);
     SetNonToken(tkobjcprotocol);
     SetNonToken(tkobjcprotocol);
+    SetNonToken(tkobjcCategory);
     end;
     end;
   'TP':
   'TP':
     SetMode(msTP7,TPModeSwitches,false);
     SetMode(msTP7,TPModeSwitches,false);
@@ -4929,11 +4933,13 @@ begin
     begin
     begin
     SetNonToken(tkobjcclass);
     SetNonToken(tkobjcclass);
     SetNonToken(tkobjcprotocol);
     SetNonToken(tkobjcprotocol);
+    SetNonToken(tkobjccategory);
     end
     end
   else
   else
     begin
     begin
     UnSetNonToken(tkobjcclass);
     UnSetNonToken(tkobjcclass);
     UnSetNonToken(tkobjcprotocol);
     UnSetNonToken(tkobjcprotocol);
+    UnSetNonToken(tkobjccategory);
     end
     end
 end;
 end;